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        // insert new users first
48        /** @var \helper_plugin_notification_cron $cron_helper */
49        $cron_helper = plugin_load('helper', 'notification_cron');
50        $cron_helper->addUsersToCron();
51
52
53        //get the oldest check
54        $res = $sqlite->query('SELECT user, MIN(timestamp) FROM cron_check');
55        $user = $sqlite->res2single($res);
56        //no user to sent notifications
57        if (!$user) return;
58
59        //update user last check
60        $sqlite->query('UPDATE cron_check SET timestamp=? WHERE user=?',  date('c'), $user);
61
62        $plugins = [];
63        trigger_event('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins);
64        $notifications_data = [
65            'plugins' => $plugins,
66            'user' => $user,
67            'notifications' => []
68        ];
69        trigger_event('PLUGIN_NOTIFICATION_GATHER', $notifications_data);
70
71        $notifications = $notifications_data['notifications'];
72        //no notifications - nothing to sent
73        if (!$notifications) return;
74
75        //get only notifications that has id
76        $notifications = array_filter($notifications, function ($notification) {
77            return array_key_exists('id', $notification);
78        });
79        //no notifications - nothing to sent
80        if (!$notifications) return;
81
82        //get the notifications that has been sent already
83        $res = $sqlite->query('SELECT plugin, notification_id FROM notification WHERE user=?', $user);
84        $sent_notifications = $sqlite->res2arr($res);
85        $sent_notifications_by_plugin = [];
86        foreach ($plugins as $plugin) {
87            $sent_notifications_by_plugin[$plugin] = [];
88        }
89        foreach ($sent_notifications as $sent_notification) {
90            $plugin = $sent_notification['plugin'];
91            $id = $sent_notification['notification_id'];
92            $sent_notifications_by_plugin[$plugin][$id] = true;
93        }
94
95        $new_notifications = [];
96        foreach ($notifications as $notification) {
97            $plugin = $notification['plugin'];
98            $id = $notification['id'];
99            if (!isset($sent_notifications_by_plugin[$plugin][$id])) {
100                $new_notifications[] = $notification;
101            }
102        }
103
104        //no notifications - nothing to sent
105        if (!$new_notifications) return;
106
107        $html = '<p>' . $this->getLang('mail content');
108        $html .= '<ul>';
109        $text = $this->getLang('mail content') . "\n\n";
110
111        usort($new_notifications, function($a, $b) {
112            if ($a['timestamp'] == $b['timestamp']) {
113                return 0;
114            }
115            return ($a['timestamp'] > $b['timestamp']) ? -1 : 1;
116        });
117
118        foreach ($new_notifications as $notification) {
119            $content = $notification['full'];
120            $timestamp = $notification['timestamp'];
121
122            $date = strftime('%d.%m %H:%M', $timestamp);
123
124            $html .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>";
125            $text .= $date . ' ' . strip_tags($content). "\n";
126        }
127        $html .= '</ul></p>';
128
129        $mail = new Mailer();
130        $userinfo = $auth->getUserData($user, $requireGroups = false);
131        $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>');
132        $mail->subject($this->getLang('mail subject'));
133        $mail->setBody($text, null, null, $html);
134        $mail->send();
135
136        //mark notifications as sent
137        foreach ($new_notifications as $notification) {
138            $plugin = $notification['plugin'];
139            $id = $notification['id'];
140            $sqlite->storeEntry('notification',
141                ['plugin' => $plugin, 'notification_id' => $id, 'user' => $user, 'sent' => date('c')]);
142        }
143
144        $event->stopPropagation();
145        $event->preventDefault();
146    }
147}
148