xref: /plugin/ireadit/helper.php (revision 49d6b1b05ca6a1bbad82408cf4bc4ef0581fe36d)
17b5bedfeSSzymon Olewniczak<?php
27b5bedfeSSzymon Olewniczak/**
37b5bedfeSSzymon Olewniczak * DokuWiki Plugin struct (Helper Component)
47b5bedfeSSzymon Olewniczak *
57b5bedfeSSzymon Olewniczak * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
67b5bedfeSSzymon Olewniczak * @author  Szymon Olewniczak <dokuwiki@cosmocode.de>
77b5bedfeSSzymon Olewniczak */
87b5bedfeSSzymon Olewniczak
97b5bedfeSSzymon Olewniczak// must be run within Dokuwiki
107b5bedfeSSzymon Olewniczakif (!defined('DOKU_INC')) {
117b5bedfeSSzymon Olewniczak    die();
127b5bedfeSSzymon Olewniczak}
137b5bedfeSSzymon Olewniczak
147b5bedfeSSzymon Olewniczakclass helper_plugin_ireadit extends DokuWiki_Plugin
157b5bedfeSSzymon Olewniczak{
16d0cab33cSSzymon Olewniczak    /**
17d0cab33cSSzymon Olewniczak     * @param array $users
18d0cab33cSSzymon Olewniczak     * @param array $groups
19d0cab33cSSzymon Olewniczak     * @return array
20d0cab33cSSzymon Olewniczak     */
21d2cf7c78SSzymon Olewniczak    public function users_set($ireadit_data) {
227b5bedfeSSzymon Olewniczak        global $auth;
237b5bedfeSSzymon Olewniczak
24d2cf7c78SSzymon Olewniczak        $users = $ireadit_data['users'];
25d2cf7c78SSzymon Olewniczak        $groups = $ireadit_data['groups'];
265d3fb867SSzymon Olewniczak        $set = [];
277b5bedfeSSzymon Olewniczak        if (empty($users) && empty($groups)) {
287b5bedfeSSzymon Olewniczak            $set = $auth->retrieveUsers();
297b5bedfeSSzymon Olewniczak        } else {
307b5bedfeSSzymon Olewniczak            $all_users = $auth->retrieveUsers();
317b5bedfeSSzymon Olewniczak            foreach ($all_users as $user => $info) {
327b5bedfeSSzymon Olewniczak                if (in_array($user, $users)) {
33d2cf7c78SSzymon Olewniczak                    $set[$user] = true;
347b5bedfeSSzymon Olewniczak                } elseif (array_intersect($groups, $info['grps'])) {
35d2cf7c78SSzymon Olewniczak                    $set[$user] = true;
367b5bedfeSSzymon Olewniczak                }
377b5bedfeSSzymon Olewniczak            }
387b5bedfeSSzymon Olewniczak        }
39d2cf7c78SSzymon Olewniczak        return array_keys($set);
40d2cf7c78SSzymon Olewniczak    }
41d2cf7c78SSzymon Olewniczak
4213f6c799SSzymon Olewniczak    public function find_last_approved($id) {
4313f6c799SSzymon Olewniczak        /** @var helper_plugin_approve $approve_helper */
4413f6c799SSzymon Olewniczak        $approve_helper = plugin_load('helper', 'approve');
4513f6c799SSzymon Olewniczak        if ($approve_helper == null) {
4613f6c799SSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
4713f6c799SSzymon Olewniczak            return null;
4813f6c799SSzymon Olewniczak        }
4913f6c799SSzymon Olewniczak
5013f6c799SSzymon Olewniczak        try {
5113f6c799SSzymon Olewniczak            /** @var \helper_plugin_approve_db $db_helper */
5213f6c799SSzymon Olewniczak            $approve_db_helper = plugin_load('helper', 'approve_db');
5313f6c799SSzymon Olewniczak            $approve_sqlite = $approve_db_helper->getDB();
5413f6c799SSzymon Olewniczak        } catch (Exception $e) {
5513f6c799SSzymon Olewniczak            msg($e->getMessage(), -1);
5613f6c799SSzymon Olewniczak            return null;
5713f6c799SSzymon Olewniczak        }
5813f6c799SSzymon Olewniczak
5913f6c799SSzymon Olewniczak        return $approve_helper->find_last_approved($approve_sqlite, $id);
6013f6c799SSzymon Olewniczak    }
6113f6c799SSzymon Olewniczak
621dbc116aSSzymon Olewniczak    public function use_approve_here($id) {
631dbc116aSSzymon Olewniczak        /** @var helper_plugin_approve $approve_helper */
641dbc116aSSzymon Olewniczak        $approve_helper = plugin_load('helper', 'approve');
651dbc116aSSzymon Olewniczak        if ($approve_helper == null) {
661dbc116aSSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
671dbc116aSSzymon Olewniczak            return null;
681dbc116aSSzymon Olewniczak        }
691dbc116aSSzymon Olewniczak
701dbc116aSSzymon Olewniczak        try {
711dbc116aSSzymon Olewniczak            /** @var \helper_plugin_approve_db $db_helper */
721dbc116aSSzymon Olewniczak            $approve_db_helper = plugin_load('helper', 'approve_db');
731dbc116aSSzymon Olewniczak            $approve_sqlite = $approve_db_helper->getDB();
741dbc116aSSzymon Olewniczak        } catch (Exception $e) {
751dbc116aSSzymon Olewniczak            msg($e->getMessage(), -1);
761dbc116aSSzymon Olewniczak            return null;
771dbc116aSSzymon Olewniczak        }
781dbc116aSSzymon Olewniczak
791dbc116aSSzymon Olewniczak        return $approve_helper->use_approve_here($approve_sqlite, $id);
801dbc116aSSzymon Olewniczak    }
811dbc116aSSzymon Olewniczak
8213f6c799SSzymon Olewniczak    public function get_approved_revs($id) {
8313f6c799SSzymon Olewniczak        try {
8413f6c799SSzymon Olewniczak            /** @var \helper_plugin_approve_db $db_helper */
8513f6c799SSzymon Olewniczak            $approve_db_helper = plugin_load('helper', 'approve_db');
8613f6c799SSzymon Olewniczak            if ($approve_db_helper == null) {
8713f6c799SSzymon Olewniczak                msg('You must install approve plugin to use ireadit-approve integration.', -1);
8813f6c799SSzymon Olewniczak                return [];
8913f6c799SSzymon Olewniczak            }
9013f6c799SSzymon Olewniczak            $approve_sqlite = $approve_db_helper->getDB();
9113f6c799SSzymon Olewniczak        } catch (Exception $e) {
9213f6c799SSzymon Olewniczak            msg($e->getMessage(), -1);
9313f6c799SSzymon Olewniczak            return [];
9413f6c799SSzymon Olewniczak        }
9513f6c799SSzymon Olewniczak
9613f6c799SSzymon Olewniczak        $res = $approve_sqlite->query('SELECT rev FROM revision WHERE page=? AND approved IS NOT NULL', $id);
9713f6c799SSzymon Olewniczak        return array_map(function ($row) {
9813f6c799SSzymon Olewniczak            return (int) $row['rev'];
9913f6c799SSzymon Olewniczak        }, $approve_sqlite->res2arr($res));
10013f6c799SSzymon Olewniczak    }
10113f6c799SSzymon Olewniczak
102*49d6b1b0SSzymon Olewniczak    public function use_ireadit_here($id, $rev) {
1031dbc116aSSzymon Olewniczak        if ($this->getConf('approve_integration') && $this->use_approve_here($id)) { // check if this is newest approve page
10413f6c799SSzymon Olewniczak            $last_approved_rev = $this->find_last_approved($id);
105*49d6b1b0SSzymon Olewniczak            if ($rev == $last_approved_rev) { // this is last approved version
106*49d6b1b0SSzymon Olewniczak                return true;
107*49d6b1b0SSzymon Olewniczak            }
108*49d6b1b0SSzymon Olewniczak        } elseif ($rev == p_get_metadata($id, 'last_change date')) { // check if it is last page revision
109*49d6b1b0SSzymon Olewniczak            return true;
110*49d6b1b0SSzymon Olewniczak        }
11113f6c799SSzymon Olewniczak        return false;
11213f6c799SSzymon Olewniczak    }
113*49d6b1b0SSzymon Olewniczak
114*49d6b1b0SSzymon Olewniczak    public function user_can_read_page($ireadit_data, $id, $rev, $user) {
115*49d6b1b0SSzymon Olewniczak        if (!$this->use_ireadit_here($id, $rev)) return false;
11613f6c799SSzymon Olewniczak
117d2cf7c78SSzymon Olewniczak        try {
118d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
119d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
120d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
121d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
122d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
12313f6c799SSzymon Olewniczak            return false;
124d2cf7c78SSzymon Olewniczak        }
125d2cf7c78SSzymon Olewniczak
126d2cf7c78SSzymon Olewniczak        $res = $sqlite->query('SELECT user, timestamp FROM ireadit
127d2cf7c78SSzymon Olewniczak                                        WHERE page = ?
128d2cf7c78SSzymon Olewniczak                                        AND rev = ?
129d2cf7c78SSzymon Olewniczak                                        ORDER BY timestamp', $id, $rev);
130d2cf7c78SSzymon Olewniczak        $readers = $sqlite->res2arr($res);
131d2cf7c78SSzymon Olewniczak        $users_set = $this->users_set($ireadit_data);
132d2cf7c78SSzymon Olewniczak        return in_array($user, $users_set) && !in_array($user, array_column($readers, 'user'));
1337b5bedfeSSzymon Olewniczak    }
134d0cab33cSSzymon Olewniczak
135d0cab33cSSzymon Olewniczak    /**
136d2cf7c78SSzymon Olewniczak     * @param $user NULL means overview mode
13713f6c799SSzymon Olewniczak     * @return array
138d0cab33cSSzymon Olewniczak     */
139d2cf7c78SSzymon Olewniczak    public function get_list($user=NULL) {
140d2cf7c78SSzymon Olewniczak        try {
141d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
142d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
143d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
144d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
145d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
14613f6c799SSzymon Olewniczak            return [];
147d0cab33cSSzymon Olewniczak        }
148d2cf7c78SSzymon Olewniczak
149d2cf7c78SSzymon Olewniczak        $indexer = idx_get_indexer();
150d2cf7c78SSzymon Olewniczak        if ($user) {
151d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->lookupKey('ireadit', $user);
152d2cf7c78SSzymon Olewniczak        } else {
153d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->getPages('ireadit');
154d2cf7c78SSzymon Olewniczak        }
155d2cf7c78SSzymon Olewniczak
156d2cf7c78SSzymon Olewniczak        $pages = [];
15713f6c799SSzymon Olewniczak        foreach ($current_user_pages as $page) {
15813f6c799SSzymon Olewniczak            $current_rev = p_get_metadata($page, 'last_change date');
15913f6c799SSzymon Olewniczak
16013f6c799SSzymon Olewniczak            $pages[$page] = [
16113f6c799SSzymon Olewniczak                'current_rev' => $current_rev,
162d2cf7c78SSzymon Olewniczak                'last_read_rev' => NULL,
163d2cf7c78SSzymon Olewniczak                'timestamp' => NULL
164d2cf7c78SSzymon Olewniczak            ];
165d2cf7c78SSzymon Olewniczak        }
166d2cf7c78SSzymon Olewniczak        if ($user) {
167d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit WHERE user=? GROUP BY page',
168d2cf7c78SSzymon Olewniczak                $user);
169d2cf7c78SSzymon Olewniczak        } else {
170d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit GROUP BY page');
171d2cf7c78SSzymon Olewniczak        }
172d2cf7c78SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
173d2cf7c78SSzymon Olewniczak            $page = $row['page'];
174d2cf7c78SSzymon Olewniczak            $rev = (int) $row['rev'];
175d2cf7c78SSzymon Olewniczak            $timestamp = $row['timestamp'];
176d2cf7c78SSzymon Olewniczak            if (isset($pages[$page])) {
177d2cf7c78SSzymon Olewniczak                $pages[$page]['last_read_rev'] = $rev;
178d2cf7c78SSzymon Olewniczak                $pages[$page]['timestamp'] = $timestamp;
179d2cf7c78SSzymon Olewniczak            }
180d2cf7c78SSzymon Olewniczak        }
1811dbc116aSSzymon Olewniczak
1821dbc116aSSzymon Olewniczak        if ($this->getConf('approve_integration')) {
1831dbc116aSSzymon Olewniczak            foreach ($current_user_pages as $page) {
1841dbc116aSSzymon Olewniczak                if (!$this->use_approve_here($page)) continue; // ignore the pages where approve doesn't apply
1851dbc116aSSzymon Olewniczak                $approved_revs = $this->get_approved_revs($page);
186*49d6b1b0SSzymon Olewniczak                if (count($approved_revs) == 0) { // page was never approved - don't list it
187*49d6b1b0SSzymon Olewniczak                    unset($pages[$page]);
188*49d6b1b0SSzymon Olewniczak                    continue;
189*49d6b1b0SSzymon Olewniczak                }
1901dbc116aSSzymon Olewniczak
1911dbc116aSSzymon Olewniczak                $current_rev = max($approved_revs);
1921dbc116aSSzymon Olewniczak                if ($user) {
1931dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE user=? AND page=? ORDER BY rev DESC',
1941dbc116aSSzymon Olewniczak                        $user, $page);
1951dbc116aSSzymon Olewniczak                } else {
1961dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE page=? ORDER BY rev DESC', $page);
1971dbc116aSSzymon Olewniczak                }
1981dbc116aSSzymon Olewniczak                $user_reads = $sqlite->res2arr($res);
1991dbc116aSSzymon Olewniczak                $last_read_rev = NULL;
2001dbc116aSSzymon Olewniczak                $last_read_timestamp = NULL;
2011dbc116aSSzymon Olewniczak                foreach ($user_reads as $row) {
2021dbc116aSSzymon Olewniczak                    $rev = (int) $row['rev'];
2031dbc116aSSzymon Olewniczak                    if (in_array($rev, $approved_revs)) {
2041dbc116aSSzymon Olewniczak                        $last_read_rev = $rev;
2051dbc116aSSzymon Olewniczak                        $last_read_timestamp = $row['timestamp'];
2061dbc116aSSzymon Olewniczak                        break;
2071dbc116aSSzymon Olewniczak                    }
2081dbc116aSSzymon Olewniczak                }
2091dbc116aSSzymon Olewniczak
2101dbc116aSSzymon Olewniczak                $pages[$page] = [
2111dbc116aSSzymon Olewniczak                    'current_rev' => $current_rev,
2121dbc116aSSzymon Olewniczak                    'last_read_rev' => $last_read_rev,
2131dbc116aSSzymon Olewniczak                    'timestamp' => $last_read_timestamp
2141dbc116aSSzymon Olewniczak                ]; // override default values
2151dbc116aSSzymon Olewniczak            }
21613f6c799SSzymon Olewniczak        }
217d2cf7c78SSzymon Olewniczak
218d2cf7c78SSzymon Olewniczak        // apply states to pages
219d2cf7c78SSzymon Olewniczak        foreach ($pages as &$page) {
220d2cf7c78SSzymon Olewniczak            if ($page['current_rev'] == $page['last_read_rev']) {
221d2cf7c78SSzymon Olewniczak                $page['state'] = 'read';
222d2cf7c78SSzymon Olewniczak            } elseif ($page['last_read_rev'] == NULL) {
223d2cf7c78SSzymon Olewniczak                $page['state'] = 'unread';
224d2cf7c78SSzymon Olewniczak            } else {
225d2cf7c78SSzymon Olewniczak                $page['state'] = 'outdated';
226d2cf7c78SSzymon Olewniczak            }
227d2cf7c78SSzymon Olewniczak        }
228d2cf7c78SSzymon Olewniczak        return $pages;
229d2cf7c78SSzymon Olewniczak    }
2307b5bedfeSSzymon Olewniczak}
231