xref: /plugin/ireadit/helper.php (revision 62105ebd375b3bc89d3c622525667ce80554a64e)
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) {
43*62105ebdSSzymon Olewniczak        /** @var helper_plugin_approve_db $approve_db */
44*62105ebdSSzymon Olewniczak        $approve_db = plugin_load('helper', 'approve_db');
45*62105ebdSSzymon Olewniczak        if ($approve_db == null) {
4613f6c799SSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
4713f6c799SSzymon Olewniczak            return null;
4813f6c799SSzymon Olewniczak        }
4913f6c799SSzymon Olewniczak
50*62105ebdSSzymon Olewniczak        return $approve_db->getLastDbRev($id, 'approved');
5113f6c799SSzymon Olewniczak    }
5213f6c799SSzymon Olewniczak
531dbc116aSSzymon Olewniczak    public function use_approve_here($id) {
54*62105ebdSSzymon Olewniczak        /** @var helper_plugin_approve_acl $approve_acl */
55*62105ebdSSzymon Olewniczak        $approve_acl = plugin_load('helper', 'approve_acl');
56*62105ebdSSzymon Olewniczak        if ($approve_acl == null) {
571dbc116aSSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
581dbc116aSSzymon Olewniczak            return null;
591dbc116aSSzymon Olewniczak        }
601dbc116aSSzymon Olewniczak
61*62105ebdSSzymon Olewniczak        return $approve_acl->useApproveHere($id);
621dbc116aSSzymon Olewniczak    }
631dbc116aSSzymon Olewniczak
6413f6c799SSzymon Olewniczak    public function get_approved_revs($id) {
65*62105ebdSSzymon Olewniczak        /** @var helper_plugin_approve_db $approve_db */
66*62105ebdSSzymon Olewniczak        $approve_db = plugin_load('helper', 'approve_db');
67*62105ebdSSzymon Olewniczak        if ($approve_db == null) {
68*62105ebdSSzymon Olewniczak            msg('You must install approve plugin to use ireadit-approve integration.', -1);
69*62105ebdSSzymon Olewniczak            return null;
70*62105ebdSSzymon Olewniczak        }
71*62105ebdSSzymon Olewniczak        $revs = $approve_db->getPageRevisions($id);
72*62105ebdSSzymon Olewniczak        $approved_revs = array_filter($revs, function ($rev) {
73*62105ebdSSzymon Olewniczak            return $rev['status'] == 'approved';
74*62105ebdSSzymon Olewniczak        });
75*62105ebdSSzymon Olewniczak        return array_map(function ($row) {
76*62105ebdSSzymon Olewniczak            return (int) $row['rev'];
77*62105ebdSSzymon Olewniczak        }, $approved_revs);
78*62105ebdSSzymon Olewniczak
7913f6c799SSzymon Olewniczak        try {
8013f6c799SSzymon Olewniczak            /** @var \helper_plugin_approve_db $db_helper */
8113f6c799SSzymon Olewniczak            $approve_db_helper = plugin_load('helper', 'approve_db');
8213f6c799SSzymon Olewniczak            if ($approve_db_helper == null) {
8313f6c799SSzymon Olewniczak                msg('You must install approve plugin to use ireadit-approve integration.', -1);
8413f6c799SSzymon Olewniczak                return [];
8513f6c799SSzymon Olewniczak            }
8613f6c799SSzymon Olewniczak            $approve_sqlite = $approve_db_helper->getDB();
8713f6c799SSzymon Olewniczak        } catch (Exception $e) {
8813f6c799SSzymon Olewniczak            msg($e->getMessage(), -1);
8913f6c799SSzymon Olewniczak            return [];
9013f6c799SSzymon Olewniczak        }
9113f6c799SSzymon Olewniczak
9213f6c799SSzymon Olewniczak        $res = $approve_sqlite->query('SELECT rev FROM revision WHERE page=? AND approved IS NOT NULL', $id);
9313f6c799SSzymon Olewniczak        return array_map(function ($row) {
9413f6c799SSzymon Olewniczak            return (int) $row['rev'];
9513f6c799SSzymon Olewniczak        }, $approve_sqlite->res2arr($res));
9613f6c799SSzymon Olewniczak    }
9713f6c799SSzymon Olewniczak
9849d6b1b0SSzymon Olewniczak    public function use_ireadit_here($id, $rev) {
991dbc116aSSzymon Olewniczak        if ($this->getConf('approve_integration') && $this->use_approve_here($id)) { // check if this is newest approve page
10013f6c799SSzymon Olewniczak            $last_approved_rev = $this->find_last_approved($id);
10149d6b1b0SSzymon Olewniczak            if ($rev == $last_approved_rev) { // this is last approved version
10249d6b1b0SSzymon Olewniczak                return true;
10349d6b1b0SSzymon Olewniczak            }
10449d6b1b0SSzymon Olewniczak        } elseif ($rev == p_get_metadata($id, 'last_change date')) { // check if it is last page revision
10549d6b1b0SSzymon Olewniczak            return true;
10649d6b1b0SSzymon Olewniczak        }
10713f6c799SSzymon Olewniczak        return false;
10813f6c799SSzymon Olewniczak    }
10949d6b1b0SSzymon Olewniczak
11049d6b1b0SSzymon Olewniczak    public function user_can_read_page($ireadit_data, $id, $rev, $user) {
11149d6b1b0SSzymon Olewniczak        if (!$this->use_ireadit_here($id, $rev)) return false;
11213f6c799SSzymon Olewniczak
113d2cf7c78SSzymon Olewniczak        try {
114d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
115d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
116d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
117d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
118d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
11913f6c799SSzymon Olewniczak            return false;
120d2cf7c78SSzymon Olewniczak        }
121d2cf7c78SSzymon Olewniczak
122d2cf7c78SSzymon Olewniczak        $res = $sqlite->query('SELECT user, timestamp FROM ireadit
123d2cf7c78SSzymon Olewniczak                                        WHERE page = ?
124d2cf7c78SSzymon Olewniczak                                        AND rev = ?
125d2cf7c78SSzymon Olewniczak                                        ORDER BY timestamp', $id, $rev);
126d2cf7c78SSzymon Olewniczak        $readers = $sqlite->res2arr($res);
127d2cf7c78SSzymon Olewniczak        $users_set = $this->users_set($ireadit_data);
128d2cf7c78SSzymon Olewniczak        return in_array($user, $users_set) && !in_array($user, array_column($readers, 'user'));
1297b5bedfeSSzymon Olewniczak    }
130d0cab33cSSzymon Olewniczak
131d0cab33cSSzymon Olewniczak    /**
132d2cf7c78SSzymon Olewniczak     * @param $user NULL means overview mode
13313f6c799SSzymon Olewniczak     * @return array
134d0cab33cSSzymon Olewniczak     */
135d2cf7c78SSzymon Olewniczak    public function get_list($user=NULL) {
136d2cf7c78SSzymon Olewniczak        try {
137d2cf7c78SSzymon Olewniczak            /** @var \helper_plugin_ireadit_db $db_helper */
138d2cf7c78SSzymon Olewniczak            $db_helper = plugin_load('helper', 'ireadit_db');
139d2cf7c78SSzymon Olewniczak            $sqlite = $db_helper->getDB();
140d2cf7c78SSzymon Olewniczak        } catch (Exception $e) {
141d2cf7c78SSzymon Olewniczak            msg($e->getMessage(), -1);
14213f6c799SSzymon Olewniczak            return [];
143d0cab33cSSzymon Olewniczak        }
144d2cf7c78SSzymon Olewniczak
145d2cf7c78SSzymon Olewniczak        $indexer = idx_get_indexer();
146d2cf7c78SSzymon Olewniczak        if ($user) {
147d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->lookupKey('ireadit', $user);
148d2cf7c78SSzymon Olewniczak        } else {
149d2cf7c78SSzymon Olewniczak            $current_user_pages = $indexer->getPages('ireadit');
150d2cf7c78SSzymon Olewniczak        }
151d2cf7c78SSzymon Olewniczak
152d2cf7c78SSzymon Olewniczak        $pages = [];
15313f6c799SSzymon Olewniczak        foreach ($current_user_pages as $page) {
15413f6c799SSzymon Olewniczak            $current_rev = p_get_metadata($page, 'last_change date');
15513f6c799SSzymon Olewniczak
15613f6c799SSzymon Olewniczak            $pages[$page] = [
15713f6c799SSzymon Olewniczak                'current_rev' => $current_rev,
158d2cf7c78SSzymon Olewniczak                'last_read_rev' => NULL,
159d2cf7c78SSzymon Olewniczak                'timestamp' => NULL
160d2cf7c78SSzymon Olewniczak            ];
161d2cf7c78SSzymon Olewniczak        }
162d2cf7c78SSzymon Olewniczak        if ($user) {
163d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit WHERE user=? GROUP BY page',
164d2cf7c78SSzymon Olewniczak                $user);
165d2cf7c78SSzymon Olewniczak        } else {
166d2cf7c78SSzymon Olewniczak            $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit GROUP BY page');
167d2cf7c78SSzymon Olewniczak        }
168d2cf7c78SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
169d2cf7c78SSzymon Olewniczak            $page = $row['page'];
170d2cf7c78SSzymon Olewniczak            $rev = (int) $row['rev'];
171d2cf7c78SSzymon Olewniczak            $timestamp = $row['timestamp'];
172d2cf7c78SSzymon Olewniczak            if (isset($pages[$page])) {
173d2cf7c78SSzymon Olewniczak                $pages[$page]['last_read_rev'] = $rev;
174d2cf7c78SSzymon Olewniczak                $pages[$page]['timestamp'] = $timestamp;
175d2cf7c78SSzymon Olewniczak            }
176d2cf7c78SSzymon Olewniczak        }
1771dbc116aSSzymon Olewniczak
1781dbc116aSSzymon Olewniczak        if ($this->getConf('approve_integration')) {
1791dbc116aSSzymon Olewniczak            foreach ($current_user_pages as $page) {
1801dbc116aSSzymon Olewniczak                if (!$this->use_approve_here($page)) continue; // ignore the pages where approve doesn't apply
1811dbc116aSSzymon Olewniczak                $approved_revs = $this->get_approved_revs($page);
18249d6b1b0SSzymon Olewniczak                if (count($approved_revs) == 0) { // page was never approved - don't list it
18349d6b1b0SSzymon Olewniczak                    unset($pages[$page]);
18449d6b1b0SSzymon Olewniczak                    continue;
18549d6b1b0SSzymon Olewniczak                }
1861dbc116aSSzymon Olewniczak
1871dbc116aSSzymon Olewniczak                $current_rev = max($approved_revs);
1881dbc116aSSzymon Olewniczak                if ($user) {
1891dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE user=? AND page=? ORDER BY rev DESC',
1901dbc116aSSzymon Olewniczak                        $user, $page);
1911dbc116aSSzymon Olewniczak                } else {
1921dbc116aSSzymon Olewniczak                    $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE page=? ORDER BY rev DESC', $page);
1931dbc116aSSzymon Olewniczak                }
1941dbc116aSSzymon Olewniczak                $user_reads = $sqlite->res2arr($res);
1951dbc116aSSzymon Olewniczak                $last_read_rev = NULL;
1961dbc116aSSzymon Olewniczak                $last_read_timestamp = NULL;
1971dbc116aSSzymon Olewniczak                foreach ($user_reads as $row) {
1981dbc116aSSzymon Olewniczak                    $rev = (int) $row['rev'];
1991dbc116aSSzymon Olewniczak                    if (in_array($rev, $approved_revs)) {
2001dbc116aSSzymon Olewniczak                        $last_read_rev = $rev;
2011dbc116aSSzymon Olewniczak                        $last_read_timestamp = $row['timestamp'];
2021dbc116aSSzymon Olewniczak                        break;
2031dbc116aSSzymon Olewniczak                    }
2041dbc116aSSzymon Olewniczak                }
2051dbc116aSSzymon Olewniczak
2061dbc116aSSzymon Olewniczak                $pages[$page] = [
2071dbc116aSSzymon Olewniczak                    'current_rev' => $current_rev,
2081dbc116aSSzymon Olewniczak                    'last_read_rev' => $last_read_rev,
2091dbc116aSSzymon Olewniczak                    'timestamp' => $last_read_timestamp
2101dbc116aSSzymon Olewniczak                ]; // override default values
2111dbc116aSSzymon Olewniczak            }
21213f6c799SSzymon Olewniczak        }
213d2cf7c78SSzymon Olewniczak
214d2cf7c78SSzymon Olewniczak        // apply states to pages
215d2cf7c78SSzymon Olewniczak        foreach ($pages as &$page) {
216d2cf7c78SSzymon Olewniczak            if ($page['current_rev'] == $page['last_read_rev']) {
217d2cf7c78SSzymon Olewniczak                $page['state'] = 'read';
218d2cf7c78SSzymon Olewniczak            } elseif ($page['last_read_rev'] == NULL) {
219d2cf7c78SSzymon Olewniczak                $page['state'] = 'unread';
220d2cf7c78SSzymon Olewniczak            } else {
221d2cf7c78SSzymon Olewniczak                $page['state'] = 'outdated';
222d2cf7c78SSzymon Olewniczak            }
223d2cf7c78SSzymon Olewniczak        }
224d2cf7c78SSzymon Olewniczak        return $pages;
225d2cf7c78SSzymon Olewniczak    }
2267b5bedfeSSzymon Olewniczak}
227