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