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 * filtering already granted acknowledgements. 187 * 188 * @param string $user 189 * @return array|bool 190 */ 191 public function getUserAssignments($user) 192 { 193 $sqlite = $this->getDB(); 194 if (!$sqlite) return false; 195 196 global $USERINFO; 197 $groups = $USERINFO['grps']; 198 199 $sql = "SELECT A.page, A.assignee, B.lastmod, C.user, C.ack FROM assignments A 200 JOIN pages B 201 ON A.page = B.page 202 LEFT JOIN acks C 203 ON A.page = C.page 204 WHERE AUTH_ISMEMBER(A.assignee, ? , ?) 205 AND ( (C.user = ? AND C.ack < B.lastmod) OR (C.user IS NOT ?) )"; 206 207 $result = $sqlite->query($sql, $user, implode(',', $groups), $user, $user); 208 $assignments = $sqlite->res2arr($result); 209 $sqlite->res_close($result); 210 211 return $assignments; 212 } 213 214 /** 215 * Returns all acknowledgements 216 * 217 * @return array|bool 218 */ 219 public function getAcknowledgements() 220 { 221 $sqlite = $this->getDB(); 222 if (!$sqlite) return false; 223 224 $sql = 'SELECT * FROM acks ORDER BY ack DESC'; 225 $result = $sqlite->query($sql); 226 $acknowledgements = $sqlite->res2arr($result); 227 $sqlite->res_close($result); 228 229 return $acknowledgements; 230 } 231} 232 233