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