1<?php
2
3/**
4 * DokuWiki Plugin notification (Action Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Szymon Olewniczak <it@rid.pl>
8 */
9
10// must be run within Dokuwiki
11if (!defined('DOKU_INC')) {
12    die();
13}
14
15class action_plugin_notification_cron extends DokuWiki_Action_Plugin
16{
17
18    /**
19     * Registers a callback function for a given event
20     *
21     * @param Doku_Event_Handler $controller DokuWiki's event controller object
22     *
23     * @return void
24     */
25    public function register(Doku_Event_Handler $controller)
26    {
27        $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'handle_indexer_tasks_run');
28    }
29
30    /**
31     *
32     * @param Doku_Event $event  event object by reference
33     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
34     *                           handler was registered]
35     *
36     * @return void
37     */
38    public function handle_indexer_tasks_run(Doku_Event $event, $param)
39    {
40        /** @var DokuWiki_Auth_Plugin $auth */
41        global $auth;
42
43        /** @var \helper_plugin_notification_db $db_helper */
44        $db_helper = plugin_load('helper', 'notification_db');
45        $sqlite = $db_helper->getDB();
46
47
48        //get the oldest check
49        $res = $sqlite->query('SELECT user, MIN(timestamp) FROM cron_check');
50        $user = $sqlite->res2single($res);
51        //no user to sent notifications
52        if (!$user) return;
53
54        //update user last check
55        $sqlite->query('UPDATE cron_check SET timestamp=? WHERE user=?',  date('c'), $user);
56
57        $plugins = [];
58        trigger_event('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins);
59        $notifications_data = [
60            'plugins' => $plugins,
61            'user' => $user,
62            'notifications' => []
63        ];
64        trigger_event('PLUGIN_NOTIFICATION_GATHER', $notifications_data);
65
66        $notifications = $notifications_data['notifications'];
67        //no notifications - nothing to sent
68        if (!$notifications) return;
69
70        //get only notifications that has id
71        $notifications = array_filter($notifications, function ($notification) {
72            return array_key_exists('id', $notification);
73        });
74        //no notifications - nothing to sent
75        if (!$notifications) return;
76
77        //get the notifications that has been sent already
78        $res = $sqlite->query('SELECT plugin, notification_id FROM notification WHERE user=?', $user);
79        $sent_notifications = $sqlite->res2arr($res);
80        $sent_notifications_by_plugin = [];
81        foreach ($plugins as $plugin) {
82            $sent_notifications_by_plugin[$plugin] = [];
83        }
84        foreach ($sent_notifications as $sent_notification) {
85            $plugin = $sent_notification['plugin'];
86            $id = $sent_notification['notification_id'];
87            $sent_notifications_by_plugin[$plugin][$id] = true;
88        }
89
90        $new_notifications = [];
91        foreach ($notifications as $notification) {
92            $plugin = $notification['plugin'];
93            $id = $notification['id'];
94            if (!isset($sent_notifications_by_plugin[$plugin][$id])) {
95                $new_notifications[] = $notification;
96            }
97        }
98
99        //no notifications - nothing to sent
100        if (!$new_notifications) return;
101
102        $html = '<p>' . $this->getLang('mail content');
103        $html .= '<ul>';
104        $text = $this->getLang('mail content') . "\n\n";
105
106        usort($new_notifications, function($a, $b) {
107            if ($a['timestamp'] == $b['timestamp']) {
108                return 0;
109            }
110            return ($a['timestamp'] > $b['timestamp']) ? -1 : 1;
111        });
112
113        foreach ($new_notifications as $notification) {
114            $content = $notification['full'];
115            $timestamp = $notification['timestamp'];
116
117            $date = strftime('%d.%m %H:%M', $timestamp);
118
119            $html .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>";
120            $text .= $date . ' ' . strip_tags($content). "\n";
121        }
122        $html .= '</ul></p>';
123
124        $mail = new Mailer();
125        $userinfo = $auth->getUserData($user, $requireGroups = false);
126        $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>');
127        $mail->subject($this->getLang('mail subject'));
128        $mail->setBody($text, null, null, $html);
129        $mail->send();
130
131        //mark notifications as sent
132        foreach ($new_notifications as $notification) {
133            $plugin = $notification['plugin'];
134            $id = $notification['id'];
135            $sqlite->storeEntry('notification',
136                ['plugin' => $plugin, 'notification_id' => $id, 'user' => $user, 'sent' => date('c')]);
137        }
138
139        $event->stopPropagation();
140        $event->preventDefault();
141    }
142}
143