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 42*13f6c799SSzymon Olewniczak public function find_last_approved($id) { 43*13f6c799SSzymon Olewniczak /** @var helper_plugin_approve $approve_helper */ 44*13f6c799SSzymon Olewniczak $approve_helper = plugin_load('helper', 'approve'); 45*13f6c799SSzymon Olewniczak if ($approve_helper == null) { 46*13f6c799SSzymon Olewniczak msg('You must install approve plugin to use ireadit-approve integration.', -1); 47*13f6c799SSzymon Olewniczak return null; 48*13f6c799SSzymon Olewniczak } 49*13f6c799SSzymon Olewniczak 50*13f6c799SSzymon Olewniczak try { 51*13f6c799SSzymon Olewniczak /** @var \helper_plugin_approve_db $db_helper */ 52*13f6c799SSzymon Olewniczak $approve_db_helper = plugin_load('helper', 'approve_db'); 53*13f6c799SSzymon Olewniczak $approve_sqlite = $approve_db_helper->getDB(); 54*13f6c799SSzymon Olewniczak } catch (Exception $e) { 55*13f6c799SSzymon Olewniczak msg($e->getMessage(), -1); 56*13f6c799SSzymon Olewniczak return null; 57*13f6c799SSzymon Olewniczak } 58*13f6c799SSzymon Olewniczak 59*13f6c799SSzymon Olewniczak return $approve_helper->find_last_approved($approve_sqlite, $id); 60*13f6c799SSzymon Olewniczak } 61*13f6c799SSzymon Olewniczak 62*13f6c799SSzymon Olewniczak public function get_approved_revs($id) { 63*13f6c799SSzymon Olewniczak try { 64*13f6c799SSzymon Olewniczak /** @var \helper_plugin_approve_db $db_helper */ 65*13f6c799SSzymon Olewniczak $approve_db_helper = plugin_load('helper', 'approve_db'); 66*13f6c799SSzymon Olewniczak if ($approve_db_helper == null) { 67*13f6c799SSzymon Olewniczak msg('You must install approve plugin to use ireadit-approve integration.', -1); 68*13f6c799SSzymon Olewniczak return []; 69*13f6c799SSzymon Olewniczak } 70*13f6c799SSzymon Olewniczak $approve_sqlite = $approve_db_helper->getDB(); 71*13f6c799SSzymon Olewniczak } catch (Exception $e) { 72*13f6c799SSzymon Olewniczak msg($e->getMessage(), -1); 73*13f6c799SSzymon Olewniczak return []; 74*13f6c799SSzymon Olewniczak } 75*13f6c799SSzymon Olewniczak 76*13f6c799SSzymon Olewniczak $res = $approve_sqlite->query('SELECT rev FROM revision WHERE page=? AND approved IS NOT NULL', $id); 77*13f6c799SSzymon Olewniczak return array_map(function ($row) { 78*13f6c799SSzymon Olewniczak return (int) $row['rev']; 79*13f6c799SSzymon Olewniczak }, $approve_sqlite->res2arr($res)); 80*13f6c799SSzymon Olewniczak } 81*13f6c799SSzymon Olewniczak 82*13f6c799SSzymon Olewniczak public function user_can_read_page($ireadit_data, $id, $rev, $user) { 83*13f6c799SSzymon Olewniczak if ($this->getConf('approve_integration')) { // check if this is newest approve page 84*13f6c799SSzymon Olewniczak $last_approved_rev = $this->find_last_approved($id); 85*13f6c799SSzymon Olewniczak if ($rev != $last_approved_rev) { // this is not last approved version 86*13f6c799SSzymon Olewniczak return false; 87*13f6c799SSzymon Olewniczak } 88*13f6c799SSzymon Olewniczak } elseif ($rev != p_get_metadata($id, 'last_change date')) { // check if it is last page revision 89*13f6c799SSzymon Olewniczak return false; 90*13f6c799SSzymon Olewniczak } 91*13f6c799SSzymon Olewniczak 92d2cf7c78SSzymon Olewniczak try { 93d2cf7c78SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 94d2cf7c78SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 95d2cf7c78SSzymon Olewniczak $sqlite = $db_helper->getDB(); 96d2cf7c78SSzymon Olewniczak } catch (Exception $e) { 97d2cf7c78SSzymon Olewniczak msg($e->getMessage(), -1); 98*13f6c799SSzymon Olewniczak return false; 99d2cf7c78SSzymon Olewniczak } 100d2cf7c78SSzymon Olewniczak 101d2cf7c78SSzymon Olewniczak $res = $sqlite->query('SELECT user, timestamp FROM ireadit 102d2cf7c78SSzymon Olewniczak WHERE page = ? 103d2cf7c78SSzymon Olewniczak AND rev = ? 104d2cf7c78SSzymon Olewniczak ORDER BY timestamp', $id, $rev); 105d2cf7c78SSzymon Olewniczak $readers = $sqlite->res2arr($res); 106d2cf7c78SSzymon Olewniczak $users_set = $this->users_set($ireadit_data); 107d2cf7c78SSzymon Olewniczak return in_array($user, $users_set) && !in_array($user, array_column($readers, 'user')); 1087b5bedfeSSzymon Olewniczak } 109d0cab33cSSzymon Olewniczak 110d0cab33cSSzymon Olewniczak /** 111d2cf7c78SSzymon Olewniczak * @param $user NULL means overview mode 112*13f6c799SSzymon Olewniczak * @return array 113d0cab33cSSzymon Olewniczak */ 114d2cf7c78SSzymon Olewniczak public function get_list($user=NULL) { 115d2cf7c78SSzymon Olewniczak try { 116d2cf7c78SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 117d2cf7c78SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 118d2cf7c78SSzymon Olewniczak $sqlite = $db_helper->getDB(); 119d2cf7c78SSzymon Olewniczak } catch (Exception $e) { 120d2cf7c78SSzymon Olewniczak msg($e->getMessage(), -1); 121*13f6c799SSzymon Olewniczak return []; 122d0cab33cSSzymon Olewniczak } 123d2cf7c78SSzymon Olewniczak 124d2cf7c78SSzymon Olewniczak $indexer = idx_get_indexer(); 125d2cf7c78SSzymon Olewniczak if ($user) { 126d2cf7c78SSzymon Olewniczak $current_user_pages = $indexer->lookupKey('ireadit', $user); 127d2cf7c78SSzymon Olewniczak } else { 128d2cf7c78SSzymon Olewniczak $current_user_pages = $indexer->getPages('ireadit'); 129d2cf7c78SSzymon Olewniczak } 130d2cf7c78SSzymon Olewniczak 131d2cf7c78SSzymon Olewniczak $pages = []; 132*13f6c799SSzymon Olewniczak if ($this->getConf('approve_integration')) { 133d2cf7c78SSzymon Olewniczak foreach ($current_user_pages as $page) { 134*13f6c799SSzymon Olewniczak $approved_revs = $this->get_approved_revs($page); 135*13f6c799SSzymon Olewniczak if (count($approved_revs) == 0) { // page was never approved - don't list it 136*13f6c799SSzymon Olewniczak continue; 137*13f6c799SSzymon Olewniczak } 138*13f6c799SSzymon Olewniczak $current_rev = max($approved_revs); 139*13f6c799SSzymon Olewniczak if ($user) { 140*13f6c799SSzymon Olewniczak $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE user=? AND page=? ORDER BY rev DESC', 141*13f6c799SSzymon Olewniczak $user, $page); 142*13f6c799SSzymon Olewniczak } else { 143*13f6c799SSzymon Olewniczak $res = $sqlite->query('SELECT rev, timestamp FROM ireadit WHERE page=? ORDER BY rev DESC', $page); 144*13f6c799SSzymon Olewniczak } 145*13f6c799SSzymon Olewniczak $user_reads = $sqlite->res2arr($res); 146*13f6c799SSzymon Olewniczak $last_read_rev = NULL; 147*13f6c799SSzymon Olewniczak $last_read_timestamp = NULL; 148*13f6c799SSzymon Olewniczak foreach ($user_reads as $row) { 149*13f6c799SSzymon Olewniczak $rev = (int) $row['rev']; 150*13f6c799SSzymon Olewniczak if (in_array($rev, $approved_revs)) { 151*13f6c799SSzymon Olewniczak $last_read_rev = $rev; 152*13f6c799SSzymon Olewniczak $last_read_timestamp = $row['timestamp']; 153*13f6c799SSzymon Olewniczak break; 154*13f6c799SSzymon Olewniczak } 155*13f6c799SSzymon Olewniczak } 156*13f6c799SSzymon Olewniczak 157d2cf7c78SSzymon Olewniczak $pages[$page] = [ 158*13f6c799SSzymon Olewniczak 'current_rev' => $current_rev, 159*13f6c799SSzymon Olewniczak 'last_read_rev' => $last_read_rev, 160*13f6c799SSzymon Olewniczak 'timestamp' => $last_read_timestamp 161*13f6c799SSzymon Olewniczak ]; 162*13f6c799SSzymon Olewniczak } 163*13f6c799SSzymon Olewniczak } else { 164*13f6c799SSzymon Olewniczak foreach ($current_user_pages as $page) { 165*13f6c799SSzymon Olewniczak $current_rev = p_get_metadata($page, 'last_change date'); 166*13f6c799SSzymon Olewniczak 167*13f6c799SSzymon Olewniczak $pages[$page] = [ 168*13f6c799SSzymon Olewniczak 'current_rev' => $current_rev, 169d2cf7c78SSzymon Olewniczak 'last_read_rev' => NULL, 170d2cf7c78SSzymon Olewniczak 'timestamp' => NULL 171d2cf7c78SSzymon Olewniczak ]; 172d2cf7c78SSzymon Olewniczak } 173d2cf7c78SSzymon Olewniczak if ($user) { 174d2cf7c78SSzymon Olewniczak $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit WHERE user=? GROUP BY page', 175d2cf7c78SSzymon Olewniczak $user); 176d2cf7c78SSzymon Olewniczak } else { 177d2cf7c78SSzymon Olewniczak $res = $sqlite->query('SELECT page, MAX(rev) as "rev", timestamp FROM ireadit GROUP BY page'); 178d2cf7c78SSzymon Olewniczak } 179d2cf7c78SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 180d2cf7c78SSzymon Olewniczak $page = $row['page']; 181d2cf7c78SSzymon Olewniczak $rev = (int) $row['rev']; 182d2cf7c78SSzymon Olewniczak $timestamp = $row['timestamp']; 183d2cf7c78SSzymon Olewniczak if (isset($pages[$page])) { 184d2cf7c78SSzymon Olewniczak $pages[$page]['last_read_rev'] = $rev; 185d2cf7c78SSzymon Olewniczak $pages[$page]['timestamp'] = $timestamp; 186d2cf7c78SSzymon Olewniczak } 187d2cf7c78SSzymon Olewniczak } 188*13f6c799SSzymon Olewniczak } 189d2cf7c78SSzymon Olewniczak 190d2cf7c78SSzymon Olewniczak // apply states to pages 191d2cf7c78SSzymon Olewniczak foreach ($pages as &$page) { 192d2cf7c78SSzymon Olewniczak if ($page['current_rev'] == $page['last_read_rev']) { 193d2cf7c78SSzymon Olewniczak $page['state'] = 'read'; 194d2cf7c78SSzymon Olewniczak } elseif ($page['last_read_rev'] == NULL) { 195d2cf7c78SSzymon Olewniczak $page['state'] = 'unread'; 196d2cf7c78SSzymon Olewniczak } else { 197d2cf7c78SSzymon Olewniczak $page['state'] = 'outdated'; 198d2cf7c78SSzymon Olewniczak } 199d2cf7c78SSzymon Olewniczak } 200d2cf7c78SSzymon Olewniczak return $pages; 201d2cf7c78SSzymon Olewniczak } 2027b5bedfeSSzymon Olewniczak} 203