xref: /plugin/acknowledge/helper.php (revision 00ddac950b6163d4f4ff6e530afdf61ae06a5980)
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, $user, $user, implode('///', $groups));
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