1<?php
2/**
3 * DokuWiki Plugin telleveryone (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Szymon Olewniczak <it@rid.pl>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14class action_plugin_telleveryone_notification extends DokuWiki_Action_Plugin
15{
16
17    /**
18     * Registers a callback function for a given event
19     *
20     * @param Doku_Event_Handler $controller DokuWiki's event controller object
21     *
22     * @return void
23     */
24    public function register(Doku_Event_Handler $controller)
25    {
26        $controller->register_hook('PLUGIN_NOTIFICATION_REGISTER_SOURCE', 'AFTER', $this, 'handle_plugin_notification_register_source');
27        $controller->register_hook('PLUGIN_NOTIFICATION_CACHE_DEPENDENCIES', 'AFTER', $this, 'handle_plugin_notification_cache_dependencies');
28        $controller->register_hook('PLUGIN_NOTIFICATION_GATHER', 'AFTER', $this, 'handle_plugin_notification_gather');
29
30    }
31
32    /**
33     * [Custom event handler which performs action]
34     *
35     * Called for event:
36     *
37     * @param Doku_Event $event  event object by reference
38     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
39     *                           handler was registered]
40     *
41     * @return void
42     */
43    public function handle_plugin_notification_register_source(Doku_Event $event, $param)
44    {
45        $event->data[] = 'telleveryone';
46    }
47
48    public function handle_plugin_notification_cache_dependencies(Doku_Event $event, $param)
49    {
50        if (!in_array('telleveryone', $event->data['plugins'])) return;
51
52        //when we use REMOTE API - we cannot use cache
53        if ($this->getConf('remote')) {
54            $event->data['_nocache'] = true;
55            return;
56        }
57
58        try {
59            /** @var \helper_plugin_telleveryone_db $db_helper */
60            $db_helper = plugin_load('helper', 'telleveryone_db');
61            $sqlite = $db_helper->getDB();
62            $event->data['dependencies'][] = $sqlite->getAdapter()->getDbFile();
63        } catch (Exception $e) {
64            msg($e->getMessage(), -1);
65            return;
66        }
67    }
68
69    public function handle_plugin_notification_gather(Doku_Event $event, $param)
70    {
71        if (!in_array('telleveryone', $event->data['plugins'])) return;
72
73        try {
74            /** @var \helper_plugin_telleveryone_db $db_helper */
75            $db_helper = plugin_load('helper', 'telleveryone_db');
76            $sqlite = $db_helper->getDB();
77        } catch (Exception $e) {
78            msg($e->getMessage(), -1);
79            return;
80        }
81
82        $q = 'SELECT id, timestamp, message_html FROM log ORDER BY timestamp DESC LIMIT ?';
83        $res = $sqlite->query($q, $this->getConf('limit'));
84
85        $logs = $sqlite->res2arr($res);
86
87        //load remote logs
88        $remote_logs_sources = array_filter(explode("\n", $this->getConf('remote')));
89        foreach ($remote_logs_sources as $source) {
90            list($url, $token) = preg_split('/\s+/', trim($source), 2);
91            if (empty($url)) continue;
92            if (empty($token)) {
93                msg('No token provided for "telleveryone" API: ' . $url, -1);
94                continue;
95            }
96            $full_url = rtrim($url, '/');
97
98            $query = http_build_query(['token' => $token, 'limit' => $this->getConf('limit')]);
99            $full_url .= '/lib/plugins/telleveryone/api.php?' . $query;
100            $result = file_get_contents($full_url);
101            if (!$result) {
102                msg('Cannot access "telleveryone" API for ' . $url, -1);
103                continue;
104            }
105            $remote_logs = json_decode($result, true);
106            $remote_logs = array_map(function ($log) use ($url) {
107                $log['id'] = $url . ':' . $log['id'];
108                return $log;
109            }, $remote_logs);
110            $logs = array_merge($logs, $remote_logs);
111        }
112
113        //sort by timestamp and remove to fit $conf['limit']
114        $timestamps = array_map('strtotime', array_column($logs, 'timestamp'));
115        array_multisort($timestamps, SORT_DESC, $logs);
116        $logs = array_slice($logs, 0, $this->getConf('limit'));
117
118        foreach ($logs as $log) {
119            $id = $log['id'];
120            $timestamp = strtotime($log['timestamp']);
121            $message = $log['message_html'];
122
123            $event->data['notifications'][] = [
124                'plugin' => 'telleveryone',
125                'id' => $id,
126                'full' => $message,
127                'brief' => $message,
128                'timestamp' => $timestamp
129            ];
130        }
131    }
132
133}
134
135