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