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