xref: /plugin/acknowledge/helper.php (revision 60ed378425250ea758995d7ccbf29fdb0aa60eb3)
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