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 return auth_isMember($memberList, $user, explode('///', $groups)); 54 } 55 56 /** 57 * Delete a page 58 * 59 * Cascades to delete all assigned data, etc. 60 * 61 * @param string $page Page ID 62 */ 63 public function removePage($page) 64 { 65 $sqlite = $this->getDB(); 66 if (!$sqlite) return; 67 68 $sql = "DELETE FROM pages WHERE page = ?"; 69 $sqlite->query($sql, $page); 70 } 71 72 /** 73 * Update last modified date of page 74 * 75 * @param string $page Page ID 76 * @param int $lastmod timestamp of last non-minor change 77 */ 78 public function storePageDate($page, $lastmod) 79 { 80 $sqlite = $this->getDB(); 81 if (!$sqlite) return; 82 83 $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)"; 84 $sqlite->query($sql, $page, $lastmod); 85 } 86 87 /** 88 * @param string $page Page ID 89 * @param string $assignees comma separated list of users and groups 90 */ 91 public function setAssignees($page, $assignees) 92 { 93 $sqlite = $this->getDB(); 94 if (!$sqlite) return; 95 96 $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)"; 97 $sqlite->query($sql, $page, $assignees); 98 } 99 100 /** 101 * Clears assignments for a page 102 * 103 * @param string $page Page ID 104 */ 105 public function clearAssignments($page) 106 { 107 $sqlite = $this->getDB(); 108 if (!$sqlite) return; 109 110 $sql = "DELETE FROM assignments WHERE page = ?"; 111 $sqlite->query($sql, $page); 112 } 113 114 115 /** 116 * Is the given user one of the assignees for this page 117 * 118 * @param string $page Page ID 119 * @param string $user user name to check 120 * @param string[] $groups groups this user is in 121 * @return bool 122 */ 123 public function isUserAssigned($page, $user, $groups) 124 { 125 $sqlite = $this->getDB(); 126 if (!$sqlite) return false; 127 128 129 $sql = "SELECT assignee FROM assignments WHERE page = ?"; 130 $result = $sqlite->query($sql, $page); 131 $assignees = (string)$sqlite->res2single($result); 132 $sqlite->res_close($result); 133 134 return auth_isMember($assignees, $user, $groups); 135 } 136 137 /** 138 * Has the given user acknowledged the given page? 139 * 140 * @param string $page 141 * @param string $user 142 * @return bool|int timestamp of acknowledgement or false 143 */ 144 public function hasUserAcknowledged($page, $user) 145 { 146 $sqlite = $this->getDB(); 147 if (!$sqlite) return false; 148 149 $sql = "SELECT ack 150 FROM acks A, pages B 151 WHERE A.page = B.page 152 AND A.page = ? 153 AND A.user = ? 154 AND A.ack >= B.lastmod"; 155 156 $result = $sqlite->query($sql, $page, $user); 157 $acktime = $sqlite->res2single($result); 158 $sqlite->res_close($result); 159 160 return $acktime ? (int)$acktime : false; 161 } 162 163 /** 164 * Save user's acknowledgement for a given page 165 * 166 * @param string $page 167 * @param string $user 168 * @return bool 169 */ 170 public function saveAcknowledgement($page, $user) 171 { 172 $sqlite = $this->getDB(); 173 if (!$sqlite) return false; 174 175 $sql = "INSERT INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))"; 176 177 $result = $sqlite->query($sql, $page, $user); 178 $sqlite->res_close($result); 179 return true; 180 181 } 182 183 /** 184 * Fetch all assignments for a given user, with additional page information, 185 * filtering already granted acknowledgements. 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 A.page, A.assignee, B.lastmod, C.user, C.ack FROM assignments A 199 JOIN pages B 200 ON A.page = B.page 201 LEFT JOIN acks C 202 ON A.page = C.page AND ( (C.user = ? AND C.ack > B.lastmod) OR (C.user IS NOT ?) ) 203 WHERE AUTH_ISMEMBER(A.assignee, ? , ?) 204 AND ack IS NULL"; 205 206 $result = $sqlite->query($sql, $user, implode('///', $groups), $user, $user); 207 $assignments = $sqlite->res2arr($result); 208 $sqlite->res_close($result); 209 210 return $assignments; 211 } 212 213 /** 214 * Returns all acknowledgements 215 * 216 * @return array|bool 217 */ 218 public function getAcknowledgements() 219 { 220 $sqlite = $this->getDB(); 221 if (!$sqlite) return false; 222 223 $sql = 'SELECT page, user, max(ack) AS ack FROM acks GROUP BY user,page ORDER BY ack DESC'; 224 $result = $sqlite->query($sql); 225 $acknowledgements = $sqlite->res2arr($result); 226 $sqlite->res_close($result); 227 228 return $acknowledgements; 229 } 230} 231 232