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