xref: /plugin/acknowledge/helper.php (revision 74126d4b5f888ba407f033d947da1ba9979f565b) !
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        return $sqlite;
29    }
30
31    /**
32     * Delete a page
33     *
34     * Cascades to delete all assigned data, etc.
35     *
36     * @param string $page Page ID
37     */
38    public function removePage($page)
39    {
40        $sqlite = $this->getDB();
41        if (!$sqlite) return;
42
43        $sql = "DELETE FROM pages WHERE page = ?";
44        $sqlite->query($sql, $page);
45    }
46
47    /**
48     * Update last modified date of page
49     *
50     * @param string $page Page ID
51     * @param int $lastmod timestamp of last non-minor change
52     */
53    public function storePageDate($page, $lastmod)
54    {
55        $sqlite = $this->getDB();
56        if (!$sqlite) return;
57
58        $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)";
59        $sqlite->query($sql, $page, $lastmod);
60    }
61
62    /**
63     * @param string $page Page ID
64     * @param string $assignees comma separated list of users and groups
65     */
66    public function setAssignees($page, $assignees)
67    {
68        $sqlite = $this->getDB();
69        if (!$sqlite) return;
70
71        $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)";
72        $sqlite->query($sql, $page, $assignees);
73    }
74
75    /**
76     * Clears assignments for a page
77     *
78     * @param string $page Page ID
79     */
80    public function clearAssignments($page)
81    {
82        $sqlite = $this->getDB();
83        if (!$sqlite) return;
84
85        $sql = "DELETE FROM assignments WHERE page = ?";
86        $sqlite->query($sql, $page);
87    }
88
89
90    /**
91     * Is the given user one of the assignees for this page
92     *
93     * @param string $page Page ID
94     * @param string $user user name to check
95     * @param string[] $groups groups this user is in
96     * @return bool
97     */
98    public function isUserAssigned($page, $user, $groups)
99    {
100        $sqlite = $this->getDB();
101        if (!$sqlite) return false;
102
103
104        $sql = "SELECT assignee FROM assignments WHERE page = ?";
105        $result = $sqlite->query($sql, $page);
106        $assignees = (string)$sqlite->res2single($result);
107        $sqlite->res_close($result);
108
109        return auth_isMember($assignees, $user, $groups);
110    }
111
112    /**
113     * Has the given user acknowledged the given page?
114     *
115     * @param string $page
116     * @param string $user
117     * @return bool|int timestamp of acknowledgement or false
118     */
119    public function hasUserAcknowledged($page, $user)
120    {
121        $sqlite = $this->getDB();
122        if (!$sqlite) return false;
123
124        $sql = "SELECT ack
125                  FROM acks A, pages B
126                 WHERE A.page = B.page
127                   AND A.page = ?
128                   AND A.user = ?
129                   AND A.ack >= B.lastmod";
130
131        $result = $sqlite->query($sql, $page, $user);
132        $acktime = $sqlite->res2single($result);
133        $sqlite->res_close($result);
134
135        return $acktime ? (int)$acktime : false;
136    }
137
138    /**
139     * Save user's acknowledgement for a given page
140     *
141     * @param string $page
142     * @param string $user
143     * @return bool
144     */
145    public function saveAcknowledgement($page, $user)
146    {
147        $sqlite = $this->getDB();
148        if (!$sqlite) return false;
149
150        $sql = "REPLACE INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))";
151
152        $result = $sqlite->query($sql, $page, $user);
153        $sqlite->res_close($result);
154        return true;
155
156    }
157
158    /**
159     * Fetch all assignments for a given user, with additional page information.
160     *
161     * @param string $user
162     * @return array|bool
163     */
164    public function getUserAssignments($user)
165    {
166        $sqlite = $this->getDB();
167        if (!$sqlite) return false;
168
169        global $USERINFO;
170        $groups = $USERINFO['grps'];
171
172        $sql = "SELECT * FROM assignments A
173                JOIN pages B
174                ON A.page = B.page
175                WHERE A.assignee LIKE ? OR A.assignee LIKE ?";
176
177        $userWildcard = '%' . $user . '%';
178        $groupWildcard = '%@' . $groups . '%';
179
180        $result = $sqlite->query($sql, $userWildcard, $groupWildcard);
181        $assignments = $sqlite->res2arr($result);
182        $sqlite->res_close($result);
183
184        return $assignments;
185    }
186
187    /**
188     * Compare user's assignments with their past acknowledgements and return only pages
189     * without or with outdated acknowledgements
190     *
191     * @param string $user
192     * @param array $assignments
193     * @return array|bool
194     */
195    public function filterAcknowledged($user, $assignments)
196    {
197        $sqlite = $this->getDB();
198        if (!$sqlite) return false;
199
200        $sql = 'SELECT * FROM acks WHERE user = ?';
201        $result = $sqlite->query($sql, $user);
202        $acknowledgements = $sqlite->res2arr($result);
203        $sqlite->res_close($result);
204
205        $listing = [];
206        $pageAcks = array_column($acknowledgements, 'ack', 'page');
207        foreach ($assignments as $assignment) {
208            if (
209                !in_array($assignment['page'], array_keys($pageAcks))
210                || (int)$assignment['lastmod'] > (int)$pageAcks[$assignment['page']]
211            ) {
212                $listing[] = $assignment;
213            }
214        }
215
216        return $listing;
217    }
218}
219
220