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