xref: /plugin/ireadit/action/ireadit.php (revision 692a14509184c6b7e10ac11e9d8c2b8e6d16b1f1)
1ce9be9e9SSzymon Olewniczak<?php
2ce9be9e9SSzymon Olewniczak// must be run within DokuWiki
3ce9be9e9SSzymon Olewniczakif (!defined('DOKU_INC')) die();
4ce9be9e9SSzymon Olewniczak
5ce9be9e9SSzymon Olewniczak/**
6ce9be9e9SSzymon Olewniczak * All DokuWiki plugins to extend the parser/rendering mechanism
7ce9be9e9SSzymon Olewniczak * need to inherit from this class
8ce9be9e9SSzymon Olewniczak */
9ce9be9e9SSzymon Olewniczakclass action_plugin_ireadit_ireadit extends DokuWiki_Action_Plugin
10ce9be9e9SSzymon Olewniczak{
11ce9be9e9SSzymon Olewniczak    public function register(Doku_Event_Handler $controller)
12ce9be9e9SSzymon Olewniczak    {
13ce9be9e9SSzymon Olewniczak        $controller->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', $this, 'render_list');
14ce9be9e9SSzymon Olewniczak        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_ireadit_action');
15ce9be9e9SSzymon Olewniczak        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'updatre_ireadit_metadata');
16ce9be9e9SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after');
17ce9be9e9SSzymon Olewniczak    }
18ce9be9e9SSzymon Olewniczak
19ce9be9e9SSzymon Olewniczak    public function render_list()
20ce9be9e9SSzymon Olewniczak    {
21ce9be9e9SSzymon Olewniczak        global $INFO, $ACT, $auth;
22ce9be9e9SSzymon Olewniczak
23ce9be9e9SSzymon Olewniczak        if ($ACT != 'show') return;
24ce9be9e9SSzymon Olewniczak        if (!p_get_metadata($INFO['id'], 'plugin ireadit')) return;
25ce9be9e9SSzymon Olewniczak
26*692a1450SSzymon Olewniczak        try {
27ce9be9e9SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
28ce9be9e9SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
29ce9be9e9SSzymon Olewniczak            $sqlite = $db_helper->getDB();
30*692a1450SSzymon Olewniczak        } catch (Exception $e) {
31*692a1450SSzymon Olewniczak            msg($e->getMessage(), -1);
32*692a1450SSzymon Olewniczak            return;
33*692a1450SSzymon Olewniczak        }
34ce9be9e9SSzymon Olewniczak
35ce9be9e9SSzymon Olewniczak        echo '<div';
36ce9be9e9SSzymon Olewniczak        if ($this->getConf('print') == 0) {
37ce9be9e9SSzymon Olewniczak            echo' class="no-print"';
38ce9be9e9SSzymon Olewniczak        }
39ce9be9e9SSzymon Olewniczak        echo '>';
40ce9be9e9SSzymon Olewniczak
41ce9be9e9SSzymon Olewniczak        $last_change_date = p_get_metadata($INFO['id'], 'last_change date');
42ce9be9e9SSzymon Olewniczak
43ce9be9e9SSzymon Olewniczak        if ($INFO['rev'] == 0) {
44ce9be9e9SSzymon Olewniczak            $res = $sqlite->query('SELECT page FROM ireadit WHERE page = ?
45ce9be9e9SSzymon Olewniczak                                                AND rev = ?
46ce9be9e9SSzymon Olewniczak                                                AND timestamp IS NULL
47ce9be9e9SSzymon Olewniczak                                                AND user = ?', $INFO['id'],
48ce9be9e9SSzymon Olewniczak                                                    $last_change_date, $INFO['client']);
49ce9be9e9SSzymon Olewniczak            if ($sqlite->res2single($res)) {
50ce9be9e9SSzymon Olewniczak                echo '<a href="' . wl($INFO['id'], ['do' => 'ireadit']) . '">' . $this->getLang('ireadit') . '</a>';
51ce9be9e9SSzymon Olewniczak            }
52ce9be9e9SSzymon Olewniczak        }
53ce9be9e9SSzymon Olewniczak
54ce9be9e9SSzymon Olewniczak        $rev = !$INFO['rev'] ? $last_change_date : $INFO['rev'];
55ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT user, timestamp FROM ireadit
56ce9be9e9SSzymon Olewniczak                                        WHERE page = ?
57ce9be9e9SSzymon Olewniczak                                        AND timestamp IS NOT NULL
58ce9be9e9SSzymon Olewniczak                                        AND rev = ?
59ce9be9e9SSzymon Olewniczak                                        ORDER BY timestamp', $INFO['id'], $rev);
60ce9be9e9SSzymon Olewniczak
61ce9be9e9SSzymon Olewniczak        $readers = $sqlite->res2arr($res);
62ce9be9e9SSzymon Olewniczak        if (count($readers) > 0) {
63ce9be9e9SSzymon Olewniczak            echo '<h3>' . $this->getLang('readit_header') . '</h3>';
64ce9be9e9SSzymon Olewniczak            echo '<ul>';
65ce9be9e9SSzymon Olewniczak            foreach ($readers as $reader) {
66ce9be9e9SSzymon Olewniczak                $udata = $auth->getUserData($reader['user'], false);
67ce9be9e9SSzymon Olewniczak                $name = $udata ? $udata['name'] : $reader['user'];
68ce9be9e9SSzymon Olewniczak                $time = strtotime($reader['timestamp']);
69ce9be9e9SSzymon Olewniczak                echo '<li>' . $name . ' - ' . date('d/m/Y H:i', $time) . '</li>';
70ce9be9e9SSzymon Olewniczak            }
71ce9be9e9SSzymon Olewniczak            echo '</ul>';
72ce9be9e9SSzymon Olewniczak        }
73ce9be9e9SSzymon Olewniczak
74ce9be9e9SSzymon Olewniczak
75ce9be9e9SSzymon Olewniczak        echo '</div>';
76ce9be9e9SSzymon Olewniczak    }
77ce9be9e9SSzymon Olewniczak
78ce9be9e9SSzymon Olewniczak    public function handle_ireadit_action(Doku_Event $event)
79ce9be9e9SSzymon Olewniczak    {
80ce9be9e9SSzymon Olewniczak        global $INFO, $ACT;
81ce9be9e9SSzymon Olewniczak        if ($event->data != 'ireadit') return;
82ce9be9e9SSzymon Olewniczak        $ACT = 'show';
83ce9be9e9SSzymon Olewniczak        if (!$INFO['client']) return;
84ce9be9e9SSzymon Olewniczak
85*692a1450SSzymon Olewniczak        try {
86ce9be9e9SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
87ce9be9e9SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
88ce9be9e9SSzymon Olewniczak            $sqlite = $db_helper->getDB();
89*692a1450SSzymon Olewniczak        } catch (Exception $e) {
90*692a1450SSzymon Olewniczak            msg($e->getMessage(), -1);
91*692a1450SSzymon Olewniczak            return;
92*692a1450SSzymon Olewniczak        }
93ce9be9e9SSzymon Olewniczak
94ce9be9e9SSzymon Olewniczak        $last_change_date = p_get_metadata($INFO['id'], 'last_change date');
95ce9be9e9SSzymon Olewniczak
96ce9be9e9SSzymon Olewniczak        //check if user can "ireadit" the page and didn't "ireadit" already
97ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT page FROM ireadit
98ce9be9e9SSzymon Olewniczak                                            WHERE page = ?
99ce9be9e9SSzymon Olewniczak                                            AND rev = ?
100ce9be9e9SSzymon Olewniczak                                            AND timestamp IS NULL
101ce9be9e9SSzymon Olewniczak                                            AND user = ?',
102ce9be9e9SSzymon Olewniczak                                        $INFO['id'], $last_change_date, $INFO['client']);
103ce9be9e9SSzymon Olewniczak        if (!$sqlite->res2single($res)) return;
104ce9be9e9SSzymon Olewniczak
105ce9be9e9SSzymon Olewniczak        $sqlite->query('UPDATE ireadit SET timestamp=? WHERE page=? AND rev=? AND user=?',
106ce9be9e9SSzymon Olewniczak            date('c'), $INFO['id'], $last_change_date, $INFO['client']);
107ce9be9e9SSzymon Olewniczak    }
108ce9be9e9SSzymon Olewniczak
109ce9be9e9SSzymon Olewniczak    public function updatre_ireadit_metadata(Doku_Event $event)
110ce9be9e9SSzymon Olewniczak    {
111*692a1450SSzymon Olewniczak        try {
112*692a1450SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
113ce9be9e9SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
114ce9be9e9SSzymon Olewniczak            $sqlite = $db_helper->getDB();
115*692a1450SSzymon Olewniczak        } catch (Exception $e) {
116*692a1450SSzymon Olewniczak            msg($e->getMessage(), -1);
117*692a1450SSzymon Olewniczak            return;
118*692a1450SSzymon Olewniczak        }
119ce9be9e9SSzymon Olewniczak
120ce9be9e9SSzymon Olewniczak        $page = $event->data['current']['last_change']['id'];
121ce9be9e9SSzymon Olewniczak        $last_change_date = $event->data['current']['last_change']['date'];
122ce9be9e9SSzymon Olewniczak
123ce9be9e9SSzymon Olewniczak        //don't use ireadit here
124ce9be9e9SSzymon Olewniczak        if (!isset($event->data['current']['plugin']['ireadit'])) {
125ce9be9e9SSzymon Olewniczak            //remove some old data
126ce9be9e9SSzymon Olewniczak            $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $page);
127ce9be9e9SSzymon Olewniczak            $sqlite->query('DELETE FROM meta WHERE page=?', $page);
128ce9be9e9SSzymon Olewniczak            return;
129ce9be9e9SSzymon Olewniczak        }
130ce9be9e9SSzymon Olewniczak        $ireadit = $event->data['current']['plugin']['ireadit'];
131ce9be9e9SSzymon Olewniczak
132ce9be9e9SSzymon Olewniczak        //check if new revision exists
133ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT page FROM ireadit WHERE page = ? AND rev = ?',
134ce9be9e9SSzymon Olewniczak            $page, $last_change_date);
135ce9be9e9SSzymon Olewniczak
136ce9be9e9SSzymon Olewniczak        //revision already in table
137ce9be9e9SSzymon Olewniczak        if ($sqlite->res2single($res)) return;
138ce9be9e9SSzymon Olewniczak
139ce9be9e9SSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
140ce9be9e9SSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
141ce9be9e9SSzymon Olewniczak
142ce9be9e9SSzymon Olewniczak        //remove old "ireaders"
143ce9be9e9SSzymon Olewniczak        $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $page);
144ce9be9e9SSzymon Olewniczak        //update metadata
145ce9be9e9SSzymon Olewniczak        $sqlite->query('REPLACE INTO meta(page,meta,last_change_date) VALUES (?,?,?)',
146ce9be9e9SSzymon Olewniczak            $page, json_encode($ireadit), $last_change_date);
147ce9be9e9SSzymon Olewniczak
148ce9be9e9SSzymon Olewniczak        if ($this->getConf('minor_edit_keeps_readers') &&
149ce9be9e9SSzymon Olewniczak            $event->data['current']['last_change']['type'] == 'e') {
150ce9be9e9SSzymon Olewniczak            $res = $sqlite->query('SELECT user, timestamp FROM ireadit
151ce9be9e9SSzymon Olewniczak                                    WHERE rev=(SELECT MAX(rev) FROM ireadit WHERE page=?)
152ce9be9e9SSzymon Olewniczak                                      AND page=? AND timestamp IS NOT NULL', $page, $page);
153ce9be9e9SSzymon Olewniczak            $prevReaders = [];
154ce9be9e9SSzymon Olewniczak            while ($row = $sqlite->res_fetch_assoc($res)) {
155ce9be9e9SSzymon Olewniczak                $user = $row['user'];
156ce9be9e9SSzymon Olewniczak                $timestamp = $row['timestamp'];
157ce9be9e9SSzymon Olewniczak                $prevReaders[$user] = $timestamp;
158ce9be9e9SSzymon Olewniczak            }
159ce9be9e9SSzymon Olewniczak        }
160ce9be9e9SSzymon Olewniczak
161ce9be9e9SSzymon Olewniczak        $newUsers = $helper->users_set($ireadit['users'], $ireadit['groups']);
162ce9be9e9SSzymon Olewniczak        //insert new users
163ce9be9e9SSzymon Olewniczak        foreach ($newUsers as $user => $info) {
164ce9be9e9SSzymon Olewniczak            if (isset($prevReaders[$user])) {
165ce9be9e9SSzymon Olewniczak                $sqlite->query('INSERT OR IGNORE INTO ireadit (page, rev, user, timestamp)
166ce9be9e9SSzymon Olewniczak                            VALUES (?,?,?,?)', $page, $last_change_date, $user, $prevReaders[$user]);
167ce9be9e9SSzymon Olewniczak            } else {
168ce9be9e9SSzymon Olewniczak                $sqlite->query('INSERT OR IGNORE INTO ireadit (page, rev, user) VALUES (?,?,?)',
169ce9be9e9SSzymon Olewniczak                    $page, $last_change_date, $user);
170ce9be9e9SSzymon Olewniczak            }
171ce9be9e9SSzymon Olewniczak        }
172ce9be9e9SSzymon Olewniczak    }
173ce9be9e9SSzymon Olewniczak
174ce9be9e9SSzymon Olewniczak    /**
175ce9be9e9SSzymon Olewniczak     *
176ce9be9e9SSzymon Olewniczak     * @param Doku_Event $event  event object by reference
177ce9be9e9SSzymon Olewniczak     * @return void
178ce9be9e9SSzymon Olewniczak     */
179ce9be9e9SSzymon Olewniczak    public function handle_pagesave_after(Doku_Event $event)
180ce9be9e9SSzymon Olewniczak    {
181ce9be9e9SSzymon Olewniczak        //no content was changed
182ce9be9e9SSzymon Olewniczak        if (!$event->data['contentChanged']) return;
183ce9be9e9SSzymon Olewniczak
184ce9be9e9SSzymon Olewniczak        if ($event->data['changeType'] == DOKU_CHANGE_TYPE_DELETE) {
185*692a1450SSzymon Olewniczak            try {
186ce9be9e9SSzymon Olewniczak                /** @var \helper_plugin_ireadit_db $db_helper */
187ce9be9e9SSzymon Olewniczak                $db_helper = plugin_load('helper', 'ireadit_db');
188ce9be9e9SSzymon Olewniczak                $sqlite = $db_helper->getDB();
189*692a1450SSzymon Olewniczak            } catch (Exception $e) {
190*692a1450SSzymon Olewniczak                msg($e->getMessage(), -1);
191*692a1450SSzymon Olewniczak                return;
192*692a1450SSzymon Olewniczak            }
193ce9be9e9SSzymon Olewniczak
194ce9be9e9SSzymon Olewniczak            $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $event->data['id']);
195ce9be9e9SSzymon Olewniczak            $sqlite->query('DELETE FROM meta WHERE page=?', $event->data['id']);
196ce9be9e9SSzymon Olewniczak        }
197ce9be9e9SSzymon Olewniczak    }
198ce9be9e9SSzymon Olewniczak}
199