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