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