1<?php 2/** 3 * DokuWiki Plugin acknowledge (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr, Anna Dabrowska <dokuwiki@cosmocode.de> 7 */ 8 9 10class helper_plugin_acknowledge extends DokuWiki_Plugin 11{ 12 13 /** 14 * @return helper_plugin_sqlite|null 15 */ 16 public function getDB() 17 { 18 /** @var \helper_plugin_sqlite $sqlite */ 19 $sqlite = plugin_load('helper', 'sqlite'); 20 if ($sqlite === null) { 21 msg($this->getLang('error sqlite plugin missing'), -1); 22 return null; 23 } 24 if (!$sqlite->init('acknowledgement', __DIR__ . '/db')) { 25 return null; 26 } 27 28 $this->registerUDF($sqlite); 29 30 return $sqlite; 31 } 32 33 /** 34 * Register user defined functions 35 * 36 * @param helper_plugin_sqlite $sqlite 37 */ 38 protected function registerUDF($sqlite) 39 { 40 $sqlite->create_function('AUTH_ISMEMBER', [$this, 'auth_isMember'], -1); 41 } 42 43 /** 44 * Wrapper function for auth_isMember which accepts groups as string 45 * 46 * @param string $memberList 47 * @param string $user 48 * @param string $groups 49 * @return bool 50 */ 51 public function auth_isMember($memberList, $user, $groups) 52 { 53 $a = 1; 54 return auth_isMember($memberList, $user, explode(',', $groups)); 55 } 56 57 /** 58 * Delete a page 59 * 60 * Cascades to delete all assigned data, etc. 61 * 62 * @param string $page Page ID 63 */ 64 public function removePage($page) 65 { 66 $sqlite = $this->getDB(); 67 if (!$sqlite) return; 68 69 $sql = "DELETE FROM pages WHERE page = ?"; 70 $sqlite->query($sql, $page); 71 } 72 73 /** 74 * Update last modified date of page 75 * 76 * @param string $page Page ID 77 * @param int $lastmod timestamp of last non-minor change 78 */ 79 public function storePageDate($page, $lastmod) 80 { 81 $sqlite = $this->getDB(); 82 if (!$sqlite) return; 83 84 $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)"; 85 $sqlite->query($sql, $page, $lastmod); 86 } 87 88 /** 89 * @param string $page Page ID 90 * @param string $assignees comma separated list of users and groups 91 */ 92 public function setAssignees($page, $assignees) 93 { 94 $sqlite = $this->getDB(); 95 if (!$sqlite) return; 96 97 $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)"; 98 $sqlite->query($sql, $page, $assignees); 99 } 100 101 /** 102 * Clears assignments for a page 103 * 104 * @param string $page Page ID 105 */ 106 public function clearAssignments($page) 107 { 108 $sqlite = $this->getDB(); 109 if (!$sqlite) return; 110 111 $sql = "DELETE FROM assignments WHERE page = ?"; 112 $sqlite->query($sql, $page); 113 } 114 115 116 /** 117 * Is the given user one of the assignees for this page 118 * 119 * @param string $page Page ID 120 * @param string $user user name to check 121 * @param string[] $groups groups this user is in 122 * @return bool 123 */ 124 public function isUserAssigned($page, $user, $groups) 125 { 126 $sqlite = $this->getDB(); 127 if (!$sqlite) return false; 128 129 130 $sql = "SELECT assignee FROM assignments WHERE page = ?"; 131 $result = $sqlite->query($sql, $page); 132 $assignees = (string)$sqlite->res2single($result); 133 $sqlite->res_close($result); 134 135 return auth_isMember($assignees, $user, $groups); 136 } 137 138 /** 139 * Has the given user acknowledged the given page? 140 * 141 * @param string $page 142 * @param string $user 143 * @return bool|int timestamp of acknowledgement or false 144 */ 145 public function hasUserAcknowledged($page, $user) 146 { 147 $sqlite = $this->getDB(); 148 if (!$sqlite) return false; 149 150 $sql = "SELECT ack 151 FROM acks A, pages B 152 WHERE A.page = B.page 153 AND A.page = ? 154 AND A.user = ? 155 AND A.ack >= B.lastmod"; 156 157 $result = $sqlite->query($sql, $page, $user); 158 $acktime = $sqlite->res2single($result); 159 $sqlite->res_close($result); 160 161 return $acktime ? (int)$acktime : false; 162 } 163 164 /** 165 * Save user's acknowledgement for a given page 166 * 167 * @param string $page 168 * @param string $user 169 * @return bool 170 */ 171 public function saveAcknowledgement($page, $user) 172 { 173 $sqlite = $this->getDB(); 174 if (!$sqlite) return false; 175 176 $sql = "REPLACE INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))"; 177 178 $result = $sqlite->query($sql, $page, $user); 179 $sqlite->res_close($result); 180 return true; 181 182 } 183 184 /** 185 * Fetch all assignments for a given user, with additional page information. 186 * 187 * @param string $user 188 * @return array|bool 189 */ 190 public function getUserAssignments($user) 191 { 192 $sqlite = $this->getDB(); 193 if (!$sqlite) return false; 194 195 global $USERINFO; 196 $groups = $USERINFO['grps']; 197 198 $sql = "SELECT * FROM assignments A 199 JOIN pages B 200 ON A.page = B.page 201 WHERE AUTH_ISMEMBER(A.assignee, ? , ?)"; 202 203 $result = $sqlite->query($sql, $user, implode(',', $groups)); 204 $assignments = $sqlite->res2arr($result); 205 $sqlite->res_close($result); 206 207 return $assignments; 208 } 209 210 /** 211 * Compare user's assignments with their past acknowledgements and return only pages 212 * without or with outdated acknowledgements 213 * 214 * @param string $user 215 * @param array $assignments 216 * @return array|bool 217 */ 218 public function filterAcknowledged($user, $assignments) 219 { 220 $sqlite = $this->getDB(); 221 if (!$sqlite) return false; 222 223 $sql = 'SELECT * FROM acks WHERE user = ?'; 224 $result = $sqlite->query($sql, $user); 225 $acknowledgements = $sqlite->res2arr($result); 226 $sqlite->res_close($result); 227 228 $listing = []; 229 $pageAcks = array_column($acknowledgements, 'ack', 'page'); 230 foreach ($assignments as $assignment) { 231 if ( 232 !in_array($assignment['page'], array_keys($pageAcks)) 233 || (int)$assignment['lastmod'] > (int)$pageAcks[$assignment['page']] 234 ) { 235 $listing[] = $assignment; 236 } 237 } 238 239 return $listing; 240 } 241 242 /** 243 * Returns all acknowledgements 244 * 245 * @return array|bool 246 */ 247 public function getAcknowledgements() 248 { 249 $sqlite = $this->getDB(); 250 if (!$sqlite) return false; 251 252 $sql = 'SELECT * FROM acks ORDER BY ack DESC'; 253 $result = $sqlite->query($sql); 254 $acknowledgements = $sqlite->res2arr($result); 255 $sqlite->res_close($result); 256 257 return $acknowledgements; 258 } 259} 260 261