1ce9be9e9SSzymon Olewniczak<?php 2ce9be9e9SSzymon Olewniczak// must be run within DokuWiki 3ce9be9e9SSzymon Olewniczakif (!defined('DOKU_INC')) die(); 4ce9be9e9SSzymon Olewniczak 5ce9be9e9SSzymon Olewniczak/** 6ce9be9e9SSzymon Olewniczak * All DokuWiki plugins to extend the parser/rendering mechanism 7ce9be9e9SSzymon Olewniczak * need to inherit from this class 8ce9be9e9SSzymon Olewniczak */ 9ce9be9e9SSzymon Olewniczakclass action_plugin_ireadit_ireadit extends DokuWiki_Action_Plugin 10ce9be9e9SSzymon Olewniczak{ 11ce9be9e9SSzymon Olewniczak public function register(Doku_Event_Handler $controller) 12ce9be9e9SSzymon Olewniczak { 13ce9be9e9SSzymon Olewniczak $controller->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', $this, 'render_list'); 14ce9be9e9SSzymon Olewniczak $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_ireadit_action'); 15ce9be9e9SSzymon Olewniczak $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'updatre_ireadit_metadata'); 16ce9be9e9SSzymon Olewniczak $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after'); 17ce9be9e9SSzymon Olewniczak } 18ce9be9e9SSzymon Olewniczak 19ce9be9e9SSzymon Olewniczak public function render_list() 20ce9be9e9SSzymon Olewniczak { 21ce9be9e9SSzymon Olewniczak global $INFO, $ACT, $auth; 22ce9be9e9SSzymon Olewniczak 23ce9be9e9SSzymon Olewniczak if ($ACT != 'show') return; 24ce9be9e9SSzymon Olewniczak if (!p_get_metadata($INFO['id'], 'plugin ireadit')) return; 25ce9be9e9SSzymon Olewniczak 26*692a1450SSzymon Olewniczak try { 27ce9be9e9SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 28ce9be9e9SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 29ce9be9e9SSzymon Olewniczak $sqlite = $db_helper->getDB(); 30*692a1450SSzymon Olewniczak } catch (Exception $e) { 31*692a1450SSzymon Olewniczak msg($e->getMessage(), -1); 32*692a1450SSzymon Olewniczak return; 33*692a1450SSzymon Olewniczak } 34ce9be9e9SSzymon Olewniczak 35ce9be9e9SSzymon Olewniczak echo '<div'; 36ce9be9e9SSzymon Olewniczak if ($this->getConf('print') == 0) { 37ce9be9e9SSzymon Olewniczak echo' class="no-print"'; 38ce9be9e9SSzymon Olewniczak } 39ce9be9e9SSzymon Olewniczak echo '>'; 40ce9be9e9SSzymon Olewniczak 41ce9be9e9SSzymon Olewniczak $last_change_date = p_get_metadata($INFO['id'], 'last_change date'); 42ce9be9e9SSzymon Olewniczak 43ce9be9e9SSzymon Olewniczak if ($INFO['rev'] == 0) { 44ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT page FROM ireadit WHERE page = ? 45ce9be9e9SSzymon Olewniczak AND rev = ? 46ce9be9e9SSzymon Olewniczak AND timestamp IS NULL 47ce9be9e9SSzymon Olewniczak AND user = ?', $INFO['id'], 48ce9be9e9SSzymon Olewniczak $last_change_date, $INFO['client']); 49ce9be9e9SSzymon Olewniczak if ($sqlite->res2single($res)) { 50ce9be9e9SSzymon Olewniczak echo '<a href="' . wl($INFO['id'], ['do' => 'ireadit']) . '">' . $this->getLang('ireadit') . '</a>'; 51ce9be9e9SSzymon Olewniczak } 52ce9be9e9SSzymon Olewniczak } 53ce9be9e9SSzymon Olewniczak 54ce9be9e9SSzymon Olewniczak $rev = !$INFO['rev'] ? $last_change_date : $INFO['rev']; 55ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT user, timestamp FROM ireadit 56ce9be9e9SSzymon Olewniczak WHERE page = ? 57ce9be9e9SSzymon Olewniczak AND timestamp IS NOT NULL 58ce9be9e9SSzymon Olewniczak AND rev = ? 59ce9be9e9SSzymon Olewniczak ORDER BY timestamp', $INFO['id'], $rev); 60ce9be9e9SSzymon Olewniczak 61ce9be9e9SSzymon Olewniczak $readers = $sqlite->res2arr($res); 62ce9be9e9SSzymon Olewniczak if (count($readers) > 0) { 63ce9be9e9SSzymon Olewniczak echo '<h3>' . $this->getLang('readit_header') . '</h3>'; 64ce9be9e9SSzymon Olewniczak echo '<ul>'; 65ce9be9e9SSzymon Olewniczak foreach ($readers as $reader) { 66ce9be9e9SSzymon Olewniczak $udata = $auth->getUserData($reader['user'], false); 67ce9be9e9SSzymon Olewniczak $name = $udata ? $udata['name'] : $reader['user']; 68ce9be9e9SSzymon Olewniczak $time = strtotime($reader['timestamp']); 69ce9be9e9SSzymon Olewniczak echo '<li>' . $name . ' - ' . date('d/m/Y H:i', $time) . '</li>'; 70ce9be9e9SSzymon Olewniczak } 71ce9be9e9SSzymon Olewniczak echo '</ul>'; 72ce9be9e9SSzymon Olewniczak } 73ce9be9e9SSzymon Olewniczak 74ce9be9e9SSzymon Olewniczak 75ce9be9e9SSzymon Olewniczak echo '</div>'; 76ce9be9e9SSzymon Olewniczak } 77ce9be9e9SSzymon Olewniczak 78ce9be9e9SSzymon Olewniczak public function handle_ireadit_action(Doku_Event $event) 79ce9be9e9SSzymon Olewniczak { 80ce9be9e9SSzymon Olewniczak global $INFO, $ACT; 81ce9be9e9SSzymon Olewniczak if ($event->data != 'ireadit') return; 82ce9be9e9SSzymon Olewniczak $ACT = 'show'; 83ce9be9e9SSzymon Olewniczak if (!$INFO['client']) return; 84ce9be9e9SSzymon Olewniczak 85*692a1450SSzymon Olewniczak try { 86ce9be9e9SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 87ce9be9e9SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 88ce9be9e9SSzymon Olewniczak $sqlite = $db_helper->getDB(); 89*692a1450SSzymon Olewniczak } catch (Exception $e) { 90*692a1450SSzymon Olewniczak msg($e->getMessage(), -1); 91*692a1450SSzymon Olewniczak return; 92*692a1450SSzymon Olewniczak } 93ce9be9e9SSzymon Olewniczak 94ce9be9e9SSzymon Olewniczak $last_change_date = p_get_metadata($INFO['id'], 'last_change date'); 95ce9be9e9SSzymon Olewniczak 96ce9be9e9SSzymon Olewniczak //check if user can "ireadit" the page and didn't "ireadit" already 97ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT page FROM ireadit 98ce9be9e9SSzymon Olewniczak WHERE page = ? 99ce9be9e9SSzymon Olewniczak AND rev = ? 100ce9be9e9SSzymon Olewniczak AND timestamp IS NULL 101ce9be9e9SSzymon Olewniczak AND user = ?', 102ce9be9e9SSzymon Olewniczak $INFO['id'], $last_change_date, $INFO['client']); 103ce9be9e9SSzymon Olewniczak if (!$sqlite->res2single($res)) return; 104ce9be9e9SSzymon Olewniczak 105ce9be9e9SSzymon Olewniczak $sqlite->query('UPDATE ireadit SET timestamp=? WHERE page=? AND rev=? AND user=?', 106ce9be9e9SSzymon Olewniczak date('c'), $INFO['id'], $last_change_date, $INFO['client']); 107ce9be9e9SSzymon Olewniczak } 108ce9be9e9SSzymon Olewniczak 109ce9be9e9SSzymon Olewniczak public function updatre_ireadit_metadata(Doku_Event $event) 110ce9be9e9SSzymon Olewniczak { 111*692a1450SSzymon Olewniczak try { 112*692a1450SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 113ce9be9e9SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 114ce9be9e9SSzymon Olewniczak $sqlite = $db_helper->getDB(); 115*692a1450SSzymon Olewniczak } catch (Exception $e) { 116*692a1450SSzymon Olewniczak msg($e->getMessage(), -1); 117*692a1450SSzymon Olewniczak return; 118*692a1450SSzymon Olewniczak } 119ce9be9e9SSzymon Olewniczak 120ce9be9e9SSzymon Olewniczak $page = $event->data['current']['last_change']['id']; 121ce9be9e9SSzymon Olewniczak $last_change_date = $event->data['current']['last_change']['date']; 122ce9be9e9SSzymon Olewniczak 123ce9be9e9SSzymon Olewniczak //don't use ireadit here 124ce9be9e9SSzymon Olewniczak if (!isset($event->data['current']['plugin']['ireadit'])) { 125ce9be9e9SSzymon Olewniczak //remove some old data 126ce9be9e9SSzymon Olewniczak $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $page); 127ce9be9e9SSzymon Olewniczak $sqlite->query('DELETE FROM meta WHERE page=?', $page); 128ce9be9e9SSzymon Olewniczak return; 129ce9be9e9SSzymon Olewniczak } 130ce9be9e9SSzymon Olewniczak $ireadit = $event->data['current']['plugin']['ireadit']; 131ce9be9e9SSzymon Olewniczak 132ce9be9e9SSzymon Olewniczak //check if new revision exists 133ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT page FROM ireadit WHERE page = ? AND rev = ?', 134ce9be9e9SSzymon Olewniczak $page, $last_change_date); 135ce9be9e9SSzymon Olewniczak 136ce9be9e9SSzymon Olewniczak //revision already in table 137ce9be9e9SSzymon Olewniczak if ($sqlite->res2single($res)) return; 138ce9be9e9SSzymon Olewniczak 139ce9be9e9SSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 140ce9be9e9SSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 141ce9be9e9SSzymon Olewniczak 142ce9be9e9SSzymon Olewniczak //remove old "ireaders" 143ce9be9e9SSzymon Olewniczak $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $page); 144ce9be9e9SSzymon Olewniczak //update metadata 145ce9be9e9SSzymon Olewniczak $sqlite->query('REPLACE INTO meta(page,meta,last_change_date) VALUES (?,?,?)', 146ce9be9e9SSzymon Olewniczak $page, json_encode($ireadit), $last_change_date); 147ce9be9e9SSzymon Olewniczak 148ce9be9e9SSzymon Olewniczak if ($this->getConf('minor_edit_keeps_readers') && 149ce9be9e9SSzymon Olewniczak $event->data['current']['last_change']['type'] == 'e') { 150ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT user, timestamp FROM ireadit 151ce9be9e9SSzymon Olewniczak WHERE rev=(SELECT MAX(rev) FROM ireadit WHERE page=?) 152ce9be9e9SSzymon Olewniczak AND page=? AND timestamp IS NOT NULL', $page, $page); 153ce9be9e9SSzymon Olewniczak $prevReaders = []; 154ce9be9e9SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 155ce9be9e9SSzymon Olewniczak $user = $row['user']; 156ce9be9e9SSzymon Olewniczak $timestamp = $row['timestamp']; 157ce9be9e9SSzymon Olewniczak $prevReaders[$user] = $timestamp; 158ce9be9e9SSzymon Olewniczak } 159ce9be9e9SSzymon Olewniczak } 160ce9be9e9SSzymon Olewniczak 161ce9be9e9SSzymon Olewniczak $newUsers = $helper->users_set($ireadit['users'], $ireadit['groups']); 162ce9be9e9SSzymon Olewniczak //insert new users 163ce9be9e9SSzymon Olewniczak foreach ($newUsers as $user => $info) { 164ce9be9e9SSzymon Olewniczak if (isset($prevReaders[$user])) { 165ce9be9e9SSzymon Olewniczak $sqlite->query('INSERT OR IGNORE INTO ireadit (page, rev, user, timestamp) 166ce9be9e9SSzymon Olewniczak VALUES (?,?,?,?)', $page, $last_change_date, $user, $prevReaders[$user]); 167ce9be9e9SSzymon Olewniczak } else { 168ce9be9e9SSzymon Olewniczak $sqlite->query('INSERT OR IGNORE INTO ireadit (page, rev, user) VALUES (?,?,?)', 169ce9be9e9SSzymon Olewniczak $page, $last_change_date, $user); 170ce9be9e9SSzymon Olewniczak } 171ce9be9e9SSzymon Olewniczak } 172ce9be9e9SSzymon Olewniczak } 173ce9be9e9SSzymon Olewniczak 174ce9be9e9SSzymon Olewniczak /** 175ce9be9e9SSzymon Olewniczak * 176ce9be9e9SSzymon Olewniczak * @param Doku_Event $event event object by reference 177ce9be9e9SSzymon Olewniczak * @return void 178ce9be9e9SSzymon Olewniczak */ 179ce9be9e9SSzymon Olewniczak public function handle_pagesave_after(Doku_Event $event) 180ce9be9e9SSzymon Olewniczak { 181ce9be9e9SSzymon Olewniczak //no content was changed 182ce9be9e9SSzymon Olewniczak if (!$event->data['contentChanged']) return; 183ce9be9e9SSzymon Olewniczak 184ce9be9e9SSzymon Olewniczak if ($event->data['changeType'] == DOKU_CHANGE_TYPE_DELETE) { 185*692a1450SSzymon Olewniczak try { 186ce9be9e9SSzymon Olewniczak /** @var \helper_plugin_ireadit_db $db_helper */ 187ce9be9e9SSzymon Olewniczak $db_helper = plugin_load('helper', 'ireadit_db'); 188ce9be9e9SSzymon Olewniczak $sqlite = $db_helper->getDB(); 189*692a1450SSzymon Olewniczak } catch (Exception $e) { 190*692a1450SSzymon Olewniczak msg($e->getMessage(), -1); 191*692a1450SSzymon Olewniczak return; 192*692a1450SSzymon Olewniczak } 193ce9be9e9SSzymon Olewniczak 194ce9be9e9SSzymon Olewniczak $sqlite->query('DELETE FROM ireadit WHERE page=? AND timestamp IS NULL', $event->data['id']); 195ce9be9e9SSzymon Olewniczak $sqlite->query('DELETE FROM meta WHERE page=?', $event->data['id']); 196ce9be9e9SSzymon Olewniczak } 197ce9be9e9SSzymon Olewniczak } 198ce9be9e9SSzymon Olewniczak} 199