xref: /plugin/ireadit/helper.php (revision 1dbc116a80009e90623aa68eb1f113fffd3a0463)
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
62*1dbc116aSSzymon Olewniczak    public function use_approve_here($id) {
63*1dbc116aSSzymon Olewniczak        /** @var helper_plugin_approve $approve_helper */
64*1dbc116aSSzymon Olewniczak        $approve_helper = plugin_load('helper', 'approve');
65*1dbc116aSSzymon Olewniczak        if ($approve_helper == null) {
66*1dbc116aSSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
67*1dbc116aSSzymon Olewniczak            return null;
68*1dbc116aSSzymon Olewniczak        }
69*1dbc116aSSzymon Olewniczak
70*1dbc116aSSzymon Olewniczak        try {
71*1dbc116aSSzymon Olewniczak            /** @var \helper_plugin_approve_db $db_helper */
72*1dbc116aSSzymon Olewniczak            $approve_db_helper = plugin_load('helper', 'approve_db');
73*1dbc116aSSzymon Olewniczak            $approve_sqlite = $approve_db_helper->getDB();
74*1dbc116aSSzymon Olewniczak        } catch (Exception $e) {
75*1dbc116aSSzymon Olewniczak            msg($e->getMessage(), -1);
76*1dbc116aSSzymon Olewniczak            return null;
77*1dbc116aSSzymon Olewniczak        }
78*1dbc116aSSzymon Olewniczak
79*1dbc116aSSzymon Olewniczak        return $approve_helper->use_approve_here($approve_sqlite, $id);
80*1dbc116aSSzymon Olewniczak    }
81*1dbc116aSSzymon 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
10213f6c799SSzymon Olewniczak    public function user_can_read_page($ireadit_data, $id, $rev, $user) {
103*1dbc116aSSzymon 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);
10513f6c799SSzymon Olewniczak            if ($rev != $last_approved_rev) { // this is not last approved version
10613f6c799SSzymon Olewniczak                return false;
10713f6c799SSzymon Olewniczak            }
10813f6c799SSzymon Olewniczak        } elseif ($rev != p_get_metadata($id, 'last_change date')) { // check if it is last page revision
10913f6c799SSzymon Olewniczak            return false;
11013f6c799SSzymon Olewniczak        }
11113f6c799SSzymon Olewniczak
112d2cf7c78SSzymon Olewniczak        try {
113d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
114d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
115d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
116d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
117d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
11813f6c799SSzymon Olewniczak            return false;
119d2cf7c78SSzymon Olewniczak        }
120d2cf7c78SSzymon Olewniczak
121d2cf7c78SSzymon Olewniczak        $res = $sqlite->query('SELECT user, timestamp FROM ireadit
122d2cf7c78SSzymon Olewniczak                                        WHERE page = ?
123d2cf7c78SSzymon Olewniczak                                        AND rev = ?
124d2cf7c78SSzymon Olewniczak                                        ORDER BY timestamp', $id, $rev);
125d2cf7c78SSzymon Olewniczak        $readers = $sqlite->res2arr($res);
126d2cf7c78SSzymon Olewniczak        $users_set = $this->users_set($ireadit_data);
127d2cf7c78SSzymon Olewniczak        return in_array($user, $users_set) && !in_array($user, array_column($readers, 'user'));
1287b5bedfeSSzymon Olewniczak    }
129d0cab33cSSzymon Olewniczak
130d0cab33cSSzymon Olewniczak    /**
131d2cf7c78SSzymon Olewniczak     * @param $user NULL means overview mode
13213f6c799SSzymon Olewniczak     * @return array
133d0cab33cSSzymon Olewniczak     */
134d2cf7c78SSzymon Olewniczak    public function get_list($user=NULL) {
135d2cf7c78SSzymon Olewniczak        try {
136d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
137d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
138d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
139d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
140d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
14113f6c799SSzymon Olewniczak            return [];
142d0cab33cSSzymon Olewniczak        }
143d2cf7c78SSzymon Olewniczak
144d2cf7c78SSzymon Olewniczak        $indexer = idx_get_indexer();
145d2cf7c78SSzymon Olewniczak        if ($user) {
146d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->lookupKey('ireadit', $user);
147d2cf7c78SSzymon Olewniczak        } else {
148d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->getPages('ireadit');
149d2cf7c78SSzymon Olewniczak        }
150d2cf7c78SSzymon Olewniczak
151d2cf7c78SSzymon Olewniczak        $pages = [];
15213f6c799SSzymon Olewniczak        foreach ($current_user_pages as $page) {
15313f6c799SSzymon Olewniczak            $current_rev = p_get_metadata($page, 'last_change date');
15413f6c799SSzymon Olewniczak
15513f6c799SSzymon Olewniczak            $pages[$page] = [
15613f6c799SSzymon Olewniczak                'current_rev' => $current_rev,
157d2cf7c78SSzymon Olewniczak                'last_read_rev' => NULL,
158d2cf7c78SSzymon Olewniczak                'timestamp' => NULL
159d2cf7c78SSzymon Olewniczak            ];
160d2cf7c78SSzymon Olewniczak        }
161d2cf7c78SSzymon Olewniczak        if ($user) {
162d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit WHERE user=? GROUP BY page',
163d2cf7c78SSzymon Olewniczak                $user);
164d2cf7c78SSzymon Olewniczak        } else {
165d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit GROUP BY page');
166d2cf7c78SSzymon Olewniczak        }
167d2cf7c78SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
168d2cf7c78SSzymon Olewniczak            $page = $row['page'];
169d2cf7c78SSzymon Olewniczak            $rev = (int) $row['rev'];
170d2cf7c78SSzymon Olewniczak            $timestamp = $row['timestamp'];
171d2cf7c78SSzymon Olewniczak            if (isset($pages[$page])) {
172d2cf7c78SSzymon Olewniczak                $pages[$page]['last_read_rev'] = $rev;
173d2cf7c78SSzymon Olewniczak                $pages[$page]['timestamp'] = $timestamp;
174d2cf7c78SSzymon Olewniczak            }
175d2cf7c78SSzymon Olewniczak        }
176*1dbc116aSSzymon Olewniczak
177*1dbc116aSSzymon Olewniczak        if ($this->getConf('approve_integration')) {
178*1dbc116aSSzymon Olewniczak            foreach ($current_user_pages as $page) {
179*1dbc116aSSzymon Olewniczak                if (!$this->use_approve_here($page)) continue; // ignore the pages where approve doesn't apply
180*1dbc116aSSzymon Olewniczak                $approved_revs = $this->get_approved_revs($page);
181*1dbc116aSSzymon Olewniczak                if (count($approved_revs) == 0) unset($pages[$page]); // page was never approved - don't list it
182*1dbc116aSSzymon Olewniczak
183*1dbc116aSSzymon Olewniczak                $current_rev = max($approved_revs);
184*1dbc116aSSzymon Olewniczak                if ($user) {
185*1dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE user=? AND page=? ORDER BY rev DESC',
186*1dbc116aSSzymon Olewniczak                        $user, $page);
187*1dbc116aSSzymon Olewniczak                } else {
188*1dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE page=? ORDER BY rev DESC', $page);
189*1dbc116aSSzymon Olewniczak                }
190*1dbc116aSSzymon Olewniczak                $user_reads = $sqlite->res2arr($res);
191*1dbc116aSSzymon Olewniczak                $last_read_rev = NULL;
192*1dbc116aSSzymon Olewniczak                $last_read_timestamp = NULL;
193*1dbc116aSSzymon Olewniczak                foreach ($user_reads as $row) {
194*1dbc116aSSzymon Olewniczak                    $rev = (int) $row['rev'];
195*1dbc116aSSzymon Olewniczak                    if (in_array($rev, $approved_revs)) {
196*1dbc116aSSzymon Olewniczak                        $last_read_rev = $rev;
197*1dbc116aSSzymon Olewniczak                        $last_read_timestamp = $row['timestamp'];
198*1dbc116aSSzymon Olewniczak                        break;
199*1dbc116aSSzymon Olewniczak                    }
200*1dbc116aSSzymon Olewniczak                }
201*1dbc116aSSzymon Olewniczak
202*1dbc116aSSzymon Olewniczak                $pages[$page] = [
203*1dbc116aSSzymon Olewniczak                    'current_rev' => $current_rev,
204*1dbc116aSSzymon Olewniczak                    'last_read_rev' => $last_read_rev,
205*1dbc116aSSzymon Olewniczak                    'timestamp' => $last_read_timestamp
206*1dbc116aSSzymon Olewniczak                ]; // override default values
207*1dbc116aSSzymon Olewniczak            }
20813f6c799SSzymon Olewniczak        }
209d2cf7c78SSzymon Olewniczak
210d2cf7c78SSzymon Olewniczak        // apply states to pages
211d2cf7c78SSzymon Olewniczak        foreach ($pages as &$page) {
212d2cf7c78SSzymon Olewniczak            if ($page['current_rev'] == $page['last_read_rev']) {
213d2cf7c78SSzymon Olewniczak                $page['state'] = 'read';
214d2cf7c78SSzymon Olewniczak            } elseif ($page['last_read_rev'] == NULL) {
215d2cf7c78SSzymon Olewniczak                $page['state'] = 'unread';
216d2cf7c78SSzymon Olewniczak            } else {
217d2cf7c78SSzymon Olewniczak                $page['state'] = 'outdated';
218d2cf7c78SSzymon Olewniczak            }
219d2cf7c78SSzymon Olewniczak        }
220d2cf7c78SSzymon Olewniczak        return $pages;
221d2cf7c78SSzymon Olewniczak    }
2227b5bedfeSSzymon Olewniczak}
223