14d6d17d0SAndreas Gohr<?php 24d6d17d0SAndreas Gohr/** 34d6d17d0SAndreas Gohr * DokuWiki Plugin acknowledge (Helper Component) 44d6d17d0SAndreas Gohr * 54d6d17d0SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 64d6d17d0SAndreas Gohr * @author Andreas Gohr, Anna Dabrowska <dokuwiki@cosmocode.de> 74d6d17d0SAndreas Gohr */ 84d6d17d0SAndreas Gohr 94d6d17d0SAndreas Gohr 104d6d17d0SAndreas Gohrclass helper_plugin_acknowledge extends DokuWiki_Plugin 114d6d17d0SAndreas Gohr{ 124d6d17d0SAndreas Gohr 13cabb51d3SAndreas Gohr /** 14cabb51d3SAndreas Gohr * @return helper_plugin_sqlite|null 15cabb51d3SAndreas Gohr */ 16cabb51d3SAndreas Gohr public function getDB() 17cabb51d3SAndreas Gohr { 18cabb51d3SAndreas Gohr /** @var \helper_plugin_sqlite $sqlite */ 19cabb51d3SAndreas Gohr $sqlite = plugin_load('helper', 'sqlite'); 20cabb51d3SAndreas Gohr if ($sqlite === null) { 21cabb51d3SAndreas Gohr msg($this->getLang('error sqlite plugin missing'), -1); 22cabb51d3SAndreas Gohr return null; 23cabb51d3SAndreas Gohr } 24cabb51d3SAndreas Gohr if (!$sqlite->init('acknowledgement', __DIR__ . '/db')) { 25cabb51d3SAndreas Gohr return null; 26cabb51d3SAndreas Gohr } 27cabb51d3SAndreas Gohr 28*9c3eae1eSAnna Dabrowska $this->registerUDF($sqlite); 29*9c3eae1eSAnna Dabrowska 30cabb51d3SAndreas Gohr return $sqlite; 31cabb51d3SAndreas Gohr } 32cabb51d3SAndreas Gohr 33cabb51d3SAndreas Gohr /** 34*9c3eae1eSAnna Dabrowska * Register user defined functions 35*9c3eae1eSAnna Dabrowska * 36*9c3eae1eSAnna Dabrowska * @param helper_plugin_sqlite $sqlite 37*9c3eae1eSAnna Dabrowska */ 38*9c3eae1eSAnna Dabrowska protected function registerUDF($sqlite) 39*9c3eae1eSAnna Dabrowska { 40*9c3eae1eSAnna Dabrowska $sqlite->create_function('AUTH_ISMEMBER', [$this, 'auth_isMember'], -1); 41*9c3eae1eSAnna Dabrowska } 42*9c3eae1eSAnna Dabrowska 43*9c3eae1eSAnna Dabrowska /** 44*9c3eae1eSAnna Dabrowska * Wrapper function for auth_isMember which accepts groups as string 45*9c3eae1eSAnna Dabrowska * 46*9c3eae1eSAnna Dabrowska * @param string $memberList 47*9c3eae1eSAnna Dabrowska * @param string $user 48*9c3eae1eSAnna Dabrowska * @param string $groups 49*9c3eae1eSAnna Dabrowska * @return bool 50*9c3eae1eSAnna Dabrowska */ 51*9c3eae1eSAnna Dabrowska public function auth_isMember($memberList, $user, $groups) 52*9c3eae1eSAnna Dabrowska { 53*9c3eae1eSAnna Dabrowska $a = 1; 54*9c3eae1eSAnna Dabrowska return auth_isMember($memberList, $user, explode(',', $groups)); 55*9c3eae1eSAnna Dabrowska } 56*9c3eae1eSAnna Dabrowska 57*9c3eae1eSAnna Dabrowska /** 58ef3ab392SAndreas Gohr * Delete a page 59ef3ab392SAndreas Gohr * 60ef3ab392SAndreas Gohr * Cascades to delete all assigned data, etc. 61ef3ab392SAndreas Gohr * 62ef3ab392SAndreas Gohr * @param string $page Page ID 63ef3ab392SAndreas Gohr */ 64ef3ab392SAndreas Gohr public function removePage($page) 65ef3ab392SAndreas Gohr { 66ef3ab392SAndreas Gohr $sqlite = $this->getDB(); 67ef3ab392SAndreas Gohr if (!$sqlite) return; 68ef3ab392SAndreas Gohr 69ef3ab392SAndreas Gohr $sql = "DELETE FROM pages WHERE page = ?"; 70ef3ab392SAndreas Gohr $sqlite->query($sql, $page); 71ef3ab392SAndreas Gohr } 72ef3ab392SAndreas Gohr 73ef3ab392SAndreas Gohr /** 74ef3ab392SAndreas Gohr * Update last modified date of page 75ef3ab392SAndreas Gohr * 76ef3ab392SAndreas Gohr * @param string $page Page ID 77ef3ab392SAndreas Gohr * @param int $lastmod timestamp of last non-minor change 78ef3ab392SAndreas Gohr */ 79ef3ab392SAndreas Gohr public function storePageDate($page, $lastmod) 80ef3ab392SAndreas Gohr { 81ef3ab392SAndreas Gohr $sqlite = $this->getDB(); 82ef3ab392SAndreas Gohr if (!$sqlite) return; 83ef3ab392SAndreas Gohr 84ef3ab392SAndreas Gohr $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)"; 85ef3ab392SAndreas Gohr $sqlite->query($sql, $page, $lastmod); 86ef3ab392SAndreas Gohr } 87ef3ab392SAndreas Gohr 88ef3ab392SAndreas Gohr /** 89cabb51d3SAndreas Gohr * @param string $page Page ID 90cabb51d3SAndreas Gohr * @param string $assignees comma separated list of users and groups 91cabb51d3SAndreas Gohr */ 92cabb51d3SAndreas Gohr public function setAssignees($page, $assignees) 93cabb51d3SAndreas Gohr { 94cabb51d3SAndreas Gohr $sqlite = $this->getDB(); 95cabb51d3SAndreas Gohr if (!$sqlite) return; 96cabb51d3SAndreas Gohr 97cabb51d3SAndreas Gohr $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)"; 98cabb51d3SAndreas Gohr $sqlite->query($sql, $page, $assignees); 99cabb51d3SAndreas Gohr } 100cabb51d3SAndreas Gohr 101ef3ab392SAndreas Gohr /** 1025773dd37SAnna Dabrowska * Clears assignments for a page 103ef3ab392SAndreas Gohr * 104ef3ab392SAndreas Gohr * @param string $page Page ID 105ef3ab392SAndreas Gohr */ 106ef3ab392SAndreas Gohr public function clearAssignments($page) 107ef3ab392SAndreas Gohr { 108ef3ab392SAndreas Gohr $sqlite = $this->getDB(); 109ef3ab392SAndreas Gohr if (!$sqlite) return; 110cabb51d3SAndreas Gohr 111ef3ab392SAndreas Gohr $sql = "DELETE FROM assignments WHERE page = ?"; 112ef3ab392SAndreas Gohr $sqlite->query($sql, $page); 113ef3ab392SAndreas Gohr } 114ef3ab392SAndreas Gohr 115ef3ab392SAndreas Gohr 116ef3ab392SAndreas Gohr /** 117ef3ab392SAndreas Gohr * Is the given user one of the assignees for this page 118ef3ab392SAndreas Gohr * 119ef3ab392SAndreas Gohr * @param string $page Page ID 120ef3ab392SAndreas Gohr * @param string $user user name to check 121ef3ab392SAndreas Gohr * @param string[] $groups groups this user is in 122ef3ab392SAndreas Gohr * @return bool 123ef3ab392SAndreas Gohr */ 124ef3ab392SAndreas Gohr public function isUserAssigned($page, $user, $groups) 125ef3ab392SAndreas Gohr { 126ef3ab392SAndreas Gohr $sqlite = $this->getDB(); 127ef3ab392SAndreas Gohr if (!$sqlite) return false; 128ef3ab392SAndreas Gohr 129ef3ab392SAndreas Gohr 130ef3ab392SAndreas Gohr $sql = "SELECT assignee FROM assignments WHERE page = ?"; 131ef3ab392SAndreas Gohr $result = $sqlite->query($sql, $page); 132ef3ab392SAndreas Gohr $assignees = (string)$sqlite->res2single($result); 133ef3ab392SAndreas Gohr $sqlite->res_close($result); 134ef3ab392SAndreas Gohr 135ef3ab392SAndreas Gohr return auth_isMember($assignees, $user, $groups); 136ef3ab392SAndreas Gohr } 137ef3ab392SAndreas Gohr 138ef3ab392SAndreas Gohr /** 139ef3ab392SAndreas Gohr * Has the given user acknowledged the given page? 140ef3ab392SAndreas Gohr * 141ef3ab392SAndreas Gohr * @param string $page 142ef3ab392SAndreas Gohr * @param string $user 1435773dd37SAnna Dabrowska * @return bool|int timestamp of acknowledgement or false 144ef3ab392SAndreas Gohr */ 145ef3ab392SAndreas Gohr public function hasUserAcknowledged($page, $user) 146ef3ab392SAndreas Gohr { 147ef3ab392SAndreas Gohr $sqlite = $this->getDB(); 148ef3ab392SAndreas Gohr if (!$sqlite) return false; 149ef3ab392SAndreas Gohr 150ef3ab392SAndreas Gohr $sql = "SELECT ack 151ef3ab392SAndreas Gohr FROM acks A, pages B 152ef3ab392SAndreas Gohr WHERE A.page = B.page 1535773dd37SAnna Dabrowska AND A.page = ? 1545773dd37SAnna Dabrowska AND A.user = ? 155ef3ab392SAndreas Gohr AND A.ack >= B.lastmod"; 156ef3ab392SAndreas Gohr 157ef3ab392SAndreas Gohr $result = $sqlite->query($sql, $page, $user); 158ef3ab392SAndreas Gohr $acktime = $sqlite->res2single($result); 159ef3ab392SAndreas Gohr $sqlite->res_close($result); 160ef3ab392SAndreas Gohr 161ef3ab392SAndreas Gohr return $acktime ? (int)$acktime : false; 162ef3ab392SAndreas Gohr } 1635773dd37SAnna Dabrowska 1645773dd37SAnna Dabrowska /** 1655773dd37SAnna Dabrowska * Save user's acknowledgement for a given page 1665773dd37SAnna Dabrowska * 1675773dd37SAnna Dabrowska * @param string $page 1685773dd37SAnna Dabrowska * @param string $user 1695773dd37SAnna Dabrowska * @return bool 1705773dd37SAnna Dabrowska */ 1715773dd37SAnna Dabrowska public function saveAcknowledgement($page, $user) 1725773dd37SAnna Dabrowska { 1735773dd37SAnna Dabrowska $sqlite = $this->getDB(); 1745773dd37SAnna Dabrowska if (!$sqlite) return false; 1755773dd37SAnna Dabrowska 1765773dd37SAnna Dabrowska $sql = "REPLACE INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))"; 1775773dd37SAnna Dabrowska 1785773dd37SAnna Dabrowska $result = $sqlite->query($sql, $page, $user); 1795773dd37SAnna Dabrowska $sqlite->res_close($result); 1805773dd37SAnna Dabrowska return true; 1815773dd37SAnna Dabrowska 1825773dd37SAnna Dabrowska } 18374126d4bSAnna Dabrowska 18474126d4bSAnna Dabrowska /** 18574126d4bSAnna Dabrowska * Fetch all assignments for a given user, with additional page information. 18674126d4bSAnna Dabrowska * 18774126d4bSAnna Dabrowska * @param string $user 18874126d4bSAnna Dabrowska * @return array|bool 18974126d4bSAnna Dabrowska */ 19074126d4bSAnna Dabrowska public function getUserAssignments($user) 19174126d4bSAnna Dabrowska { 19274126d4bSAnna Dabrowska $sqlite = $this->getDB(); 19374126d4bSAnna Dabrowska if (!$sqlite) return false; 19474126d4bSAnna Dabrowska 19574126d4bSAnna Dabrowska global $USERINFO; 19674126d4bSAnna Dabrowska $groups = $USERINFO['grps']; 19774126d4bSAnna Dabrowska 19874126d4bSAnna Dabrowska $sql = "SELECT * FROM assignments A 19974126d4bSAnna Dabrowska JOIN pages B 20074126d4bSAnna Dabrowska ON A.page = B.page 201*9c3eae1eSAnna Dabrowska WHERE AUTH_ISMEMBER(A.assignee, ? , ?)"; 20274126d4bSAnna Dabrowska 203*9c3eae1eSAnna Dabrowska $result = $sqlite->query($sql, $user, implode(',', $groups)); 20474126d4bSAnna Dabrowska $assignments = $sqlite->res2arr($result); 20574126d4bSAnna Dabrowska $sqlite->res_close($result); 20674126d4bSAnna Dabrowska 20774126d4bSAnna Dabrowska return $assignments; 20874126d4bSAnna Dabrowska } 20974126d4bSAnna Dabrowska 21074126d4bSAnna Dabrowska /** 21174126d4bSAnna Dabrowska * Compare user's assignments with their past acknowledgements and return only pages 21274126d4bSAnna Dabrowska * without or with outdated acknowledgements 21374126d4bSAnna Dabrowska * 21474126d4bSAnna Dabrowska * @param string $user 21574126d4bSAnna Dabrowska * @param array $assignments 21674126d4bSAnna Dabrowska * @return array|bool 21774126d4bSAnna Dabrowska */ 21874126d4bSAnna Dabrowska public function filterAcknowledged($user, $assignments) 21974126d4bSAnna Dabrowska { 22074126d4bSAnna Dabrowska $sqlite = $this->getDB(); 22174126d4bSAnna Dabrowska if (!$sqlite) return false; 22274126d4bSAnna Dabrowska 22374126d4bSAnna Dabrowska $sql = 'SELECT * FROM acks WHERE user = ?'; 22474126d4bSAnna Dabrowska $result = $sqlite->query($sql, $user); 22574126d4bSAnna Dabrowska $acknowledgements = $sqlite->res2arr($result); 22674126d4bSAnna Dabrowska $sqlite->res_close($result); 22774126d4bSAnna Dabrowska 22874126d4bSAnna Dabrowska $listing = []; 22974126d4bSAnna Dabrowska $pageAcks = array_column($acknowledgements, 'ack', 'page'); 23074126d4bSAnna Dabrowska foreach ($assignments as $assignment) { 23174126d4bSAnna Dabrowska if ( 23274126d4bSAnna Dabrowska !in_array($assignment['page'], array_keys($pageAcks)) 23374126d4bSAnna Dabrowska || (int)$assignment['lastmod'] > (int)$pageAcks[$assignment['page']] 23474126d4bSAnna Dabrowska ) { 23574126d4bSAnna Dabrowska $listing[] = $assignment; 23674126d4bSAnna Dabrowska } 23774126d4bSAnna Dabrowska } 23874126d4bSAnna Dabrowska 23974126d4bSAnna Dabrowska return $listing; 24074126d4bSAnna Dabrowska } 241d6011abdSAnna Dabrowska 242d6011abdSAnna Dabrowska /** 243d6011abdSAnna Dabrowska * Returns all acknowledgements 244d6011abdSAnna Dabrowska * 245d6011abdSAnna Dabrowska * @return array|bool 246d6011abdSAnna Dabrowska */ 247d6011abdSAnna Dabrowska public function getAcknowledgements() 248d6011abdSAnna Dabrowska { 249d6011abdSAnna Dabrowska $sqlite = $this->getDB(); 250d6011abdSAnna Dabrowska if (!$sqlite) return false; 251d6011abdSAnna Dabrowska 252d6011abdSAnna Dabrowska $sql = 'SELECT * FROM acks ORDER BY ack DESC'; 253d6011abdSAnna Dabrowska $result = $sqlite->query($sql); 254d6011abdSAnna Dabrowska $acknowledgements = $sqlite->res2arr($result); 255d6011abdSAnna Dabrowska $sqlite->res_close($result); 256d6011abdSAnna Dabrowska 257d6011abdSAnna Dabrowska return $acknowledgements; 258d6011abdSAnna Dabrowska } 2594d6d17d0SAndreas Gohr} 2604d6d17d0SAndreas Gohr 261