xref: /plugin/acknowledge/helper.php (revision c6d8c1d9cd53aea3430dbc2779c65b98dc7ee08a)
14d6d17d0SAndreas Gohr<?php
2*c6d8c1d9SAndreas Gohr
3*c6d8c1d9SAndreas Gohruse dokuwiki\Extension\AuthPlugin;
4*c6d8c1d9SAndreas Gohr
54d6d17d0SAndreas Gohr/**
64d6d17d0SAndreas Gohr * DokuWiki Plugin acknowledge (Helper Component)
74d6d17d0SAndreas Gohr *
84d6d17d0SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
94d6d17d0SAndreas Gohr * @author  Andreas Gohr, Anna Dabrowska <dokuwiki@cosmocode.de>
104d6d17d0SAndreas Gohr */
114d6d17d0SAndreas Gohrclass helper_plugin_acknowledge extends DokuWiki_Plugin
124d6d17d0SAndreas Gohr{
134d6d17d0SAndreas Gohr
14cabb51d3SAndreas Gohr    /**
15cabb51d3SAndreas Gohr     * @return helper_plugin_sqlite|null
16cabb51d3SAndreas Gohr     */
17cabb51d3SAndreas Gohr    public function getDB()
18cabb51d3SAndreas Gohr    {
19cabb51d3SAndreas Gohr        /** @var \helper_plugin_sqlite $sqlite */
20cabb51d3SAndreas Gohr        $sqlite = plugin_load('helper', 'sqlite');
21cabb51d3SAndreas Gohr        if ($sqlite === null) {
22cabb51d3SAndreas Gohr            msg($this->getLang('error sqlite plugin missing'), -1);
23cabb51d3SAndreas Gohr            return null;
24cabb51d3SAndreas Gohr        }
25cabb51d3SAndreas Gohr        if (!$sqlite->init('acknowledgement', __DIR__ . '/db')) {
26cabb51d3SAndreas Gohr            return null;
27cabb51d3SAndreas Gohr        }
28cabb51d3SAndreas Gohr
299c3eae1eSAnna Dabrowska        $this->registerUDF($sqlite);
309c3eae1eSAnna Dabrowska
31cabb51d3SAndreas Gohr        return $sqlite;
32cabb51d3SAndreas Gohr    }
33cabb51d3SAndreas Gohr
34cabb51d3SAndreas Gohr    /**
359c3eae1eSAnna Dabrowska     * Register user defined functions
369c3eae1eSAnna Dabrowska     *
379c3eae1eSAnna Dabrowska     * @param helper_plugin_sqlite $sqlite
389c3eae1eSAnna Dabrowska     */
399c3eae1eSAnna Dabrowska    protected function registerUDF($sqlite)
409c3eae1eSAnna Dabrowska    {
419c3eae1eSAnna Dabrowska        $sqlite->create_function('AUTH_ISMEMBER', [$this, 'auth_isMember'], -1);
429c3eae1eSAnna Dabrowska    }
439c3eae1eSAnna Dabrowska
449c3eae1eSAnna Dabrowska    /**
459c3eae1eSAnna Dabrowska     * Wrapper function for auth_isMember which accepts groups as string
469c3eae1eSAnna Dabrowska     *
479c3eae1eSAnna Dabrowska     * @param string $memberList
489c3eae1eSAnna Dabrowska     * @param string $user
499c3eae1eSAnna Dabrowska     * @param string $groups
509c3eae1eSAnna Dabrowska     * @return bool
519c3eae1eSAnna Dabrowska     */
529c3eae1eSAnna Dabrowska    public function auth_isMember($memberList, $user, $groups)
539c3eae1eSAnna Dabrowska    {
5495113ed8SAnna Dabrowska        return auth_isMember($memberList, $user, explode('///', $groups));
559c3eae1eSAnna Dabrowska    }
569c3eae1eSAnna Dabrowska
579c3eae1eSAnna 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    /**
745dee13f7SAnna Dabrowska     * Update last modified date of page if content has changed
75ef3ab392SAndreas Gohr     *
76ef3ab392SAndreas Gohr     * @param string $page Page ID
77ef3ab392SAndreas Gohr     * @param int $lastmod timestamp of last non-minor change
78ef3ab392SAndreas Gohr     */
795dee13f7SAnna Dabrowska    public function storePageDate($page, $lastmod, $newContent)
80ef3ab392SAndreas Gohr    {
81ed4e8871SAnna Dabrowska        $changelog = new \dokuwiki\ChangeLog\PageChangeLog($page);
82789aa26fSAnna Dabrowska        $revs = $changelog->getRevisions(0, 1);
83ed4e8871SAnna Dabrowska
84ed4e8871SAnna Dabrowska        // compare content
85ed4e8871SAnna Dabrowska        $oldContent = str_replace(NL, '', io_readFile(wikiFN($page, $revs[0])));
86ed4e8871SAnna Dabrowska        $newContent = str_replace(NL, '', $newContent);
87ed4e8871SAnna Dabrowska        if ($oldContent === $newContent) return;
88ed4e8871SAnna Dabrowska
89ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
90ef3ab392SAndreas Gohr        if (!$sqlite) return;
91ef3ab392SAndreas Gohr
92ef3ab392SAndreas Gohr        $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)";
93ef3ab392SAndreas Gohr        $sqlite->query($sql, $page, $lastmod);
94ef3ab392SAndreas Gohr    }
95ef3ab392SAndreas Gohr
96ef3ab392SAndreas Gohr    /**
97cabb51d3SAndreas Gohr     * @param string $page Page ID
98cabb51d3SAndreas Gohr     * @param string $assignees comma separated list of users and groups
99cabb51d3SAndreas Gohr     */
100cabb51d3SAndreas Gohr    public function setAssignees($page, $assignees)
101cabb51d3SAndreas Gohr    {
102cabb51d3SAndreas Gohr        $sqlite = $this->getDB();
103cabb51d3SAndreas Gohr        if (!$sqlite) return;
104cabb51d3SAndreas Gohr
105cabb51d3SAndreas Gohr        $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)";
106cabb51d3SAndreas Gohr        $sqlite->query($sql, $page, $assignees);
107cabb51d3SAndreas Gohr    }
108cabb51d3SAndreas Gohr
109ef3ab392SAndreas Gohr    /**
1105773dd37SAnna Dabrowska     * Clears assignments for a page
111ef3ab392SAndreas Gohr     *
112ef3ab392SAndreas Gohr     * @param string $page Page ID
113ef3ab392SAndreas Gohr     */
114ef3ab392SAndreas Gohr    public function clearAssignments($page)
115ef3ab392SAndreas Gohr    {
116ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
117ef3ab392SAndreas Gohr        if (!$sqlite) return;
118cabb51d3SAndreas Gohr
119ef3ab392SAndreas Gohr        $sql = "DELETE FROM assignments WHERE page = ?";
120ef3ab392SAndreas Gohr        $sqlite->query($sql, $page);
121ef3ab392SAndreas Gohr    }
122ef3ab392SAndreas Gohr
123ef3ab392SAndreas Gohr    /**
124ef3ab392SAndreas Gohr     * Is the given user one of the assignees for this page
125ef3ab392SAndreas Gohr     *
126ef3ab392SAndreas Gohr     * @param string $page Page ID
127ef3ab392SAndreas Gohr     * @param string $user user name to check
128ef3ab392SAndreas Gohr     * @param string[] $groups groups this user is in
129ef3ab392SAndreas Gohr     * @return bool
130ef3ab392SAndreas Gohr     */
131ef3ab392SAndreas Gohr    public function isUserAssigned($page, $user, $groups)
132ef3ab392SAndreas Gohr    {
133ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
134ef3ab392SAndreas Gohr        if (!$sqlite) return false;
135ef3ab392SAndreas Gohr
136ef3ab392SAndreas Gohr        $sql = "SELECT assignee FROM assignments WHERE page = ?";
137ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page);
138ef3ab392SAndreas Gohr        $assignees = (string)$sqlite->res2single($result);
139ef3ab392SAndreas Gohr        $sqlite->res_close($result);
140ef3ab392SAndreas Gohr
141ef3ab392SAndreas Gohr        return auth_isMember($assignees, $user, $groups);
142ef3ab392SAndreas Gohr    }
143ef3ab392SAndreas Gohr
144ef3ab392SAndreas Gohr    /**
145ef3ab392SAndreas Gohr     * Has the given user acknowledged the given page?
146ef3ab392SAndreas Gohr     *
147ef3ab392SAndreas Gohr     * @param string $page
148ef3ab392SAndreas Gohr     * @param string $user
1495773dd37SAnna Dabrowska     * @return bool|int timestamp of acknowledgement or false
150ef3ab392SAndreas Gohr     */
151ef3ab392SAndreas Gohr    public function hasUserAcknowledged($page, $user)
152ef3ab392SAndreas Gohr    {
153ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
154ef3ab392SAndreas Gohr        if (!$sqlite) return false;
155ef3ab392SAndreas Gohr
156ef3ab392SAndreas Gohr        $sql = "SELECT ack
157ef3ab392SAndreas Gohr                  FROM acks A, pages B
158ef3ab392SAndreas Gohr                 WHERE A.page = B.page
1595773dd37SAnna Dabrowska                   AND A.page = ?
1605773dd37SAnna Dabrowska                   AND A.user = ?
161ef3ab392SAndreas Gohr                   AND A.ack >= B.lastmod";
162ef3ab392SAndreas Gohr
163ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page, $user);
164ef3ab392SAndreas Gohr        $acktime = $sqlite->res2single($result);
165ef3ab392SAndreas Gohr        $sqlite->res_close($result);
166ef3ab392SAndreas Gohr
167ef3ab392SAndreas Gohr        return $acktime ? (int)$acktime : false;
168ef3ab392SAndreas Gohr    }
1695773dd37SAnna Dabrowska
1705773dd37SAnna Dabrowska    /**
171d9a8334dSAnna Dabrowska     * Timestamp of the latest acknowledgment of the given page
172d9a8334dSAnna Dabrowska     * by the given user
173d9a8334dSAnna Dabrowska     *
174d9a8334dSAnna Dabrowska     * @param string $page
175d9a8334dSAnna Dabrowska     * @param string $user
176d9a8334dSAnna Dabrowska     * @return bool|string
177d9a8334dSAnna Dabrowska     */
178d9a8334dSAnna Dabrowska    public function getLatestUserAcknowledgement($page, $user)
179d9a8334dSAnna Dabrowska    {
180d9a8334dSAnna Dabrowska        $sqlite = $this->getDB();
181d9a8334dSAnna Dabrowska        if (!$sqlite) return false;
182d9a8334dSAnna Dabrowska
183d9a8334dSAnna Dabrowska        $sql = "SELECT MAX(ack)
184d9a8334dSAnna Dabrowska                  FROM acks
185d9a8334dSAnna Dabrowska                 WHERE page = ?
186d9a8334dSAnna Dabrowska                   AND user = ?";
187d9a8334dSAnna Dabrowska
188d9a8334dSAnna Dabrowska        $result = $sqlite->query($sql, $page, $user);
189d9a8334dSAnna Dabrowska        $latestAck = $sqlite->res2single($result);
190d9a8334dSAnna Dabrowska        $sqlite->res_close($result);
191d9a8334dSAnna Dabrowska
192d9a8334dSAnna Dabrowska        return $latestAck;
193d9a8334dSAnna Dabrowska    }
194d9a8334dSAnna Dabrowska
195d9a8334dSAnna Dabrowska    /**
1965773dd37SAnna Dabrowska     * Save user's acknowledgement for a given page
1975773dd37SAnna Dabrowska     *
1985773dd37SAnna Dabrowska     * @param string $page
1995773dd37SAnna Dabrowska     * @param string $user
2005773dd37SAnna Dabrowska     * @return bool
2015773dd37SAnna Dabrowska     */
2025773dd37SAnna Dabrowska    public function saveAcknowledgement($page, $user)
2035773dd37SAnna Dabrowska    {
2045773dd37SAnna Dabrowska        $sqlite = $this->getDB();
2055773dd37SAnna Dabrowska        if (!$sqlite) return false;
2065773dd37SAnna Dabrowska
2078e55e483SAnna Dabrowska        $sql = "INSERT INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))";
2085773dd37SAnna Dabrowska
2095773dd37SAnna Dabrowska        $result = $sqlite->query($sql, $page, $user);
2105773dd37SAnna Dabrowska        $sqlite->res_close($result);
2115773dd37SAnna Dabrowska        return true;
2125773dd37SAnna Dabrowska
2135773dd37SAnna Dabrowska    }
21474126d4bSAnna Dabrowska
21574126d4bSAnna Dabrowska    /**
21660ed3784SAnna Dabrowska     * Fetch all assignments for a given user, with additional page information,
21760ed3784SAnna Dabrowska     * filtering already granted acknowledgements.
21874126d4bSAnna Dabrowska     *
21974126d4bSAnna Dabrowska     * @param string $user
2208c50976eSAnna Dabrowska     * @param array $groups
22174126d4bSAnna Dabrowska     * @return array|bool
22274126d4bSAnna Dabrowska     */
2238c50976eSAnna Dabrowska    public function getUserAssignments($user, $groups)
22474126d4bSAnna Dabrowska    {
22574126d4bSAnna Dabrowska        $sqlite = $this->getDB();
22674126d4bSAnna Dabrowska        if (!$sqlite) return false;
22774126d4bSAnna Dabrowska
22860ed3784SAnna Dabrowska        $sql = "SELECT A.page, A.assignee, B.lastmod, C.user, C.ack FROM assignments A
22974126d4bSAnna Dabrowska                JOIN pages B
23074126d4bSAnna Dabrowska                ON A.page = B.page
23160ed3784SAnna Dabrowska                LEFT JOIN acks C
2322541208bSAnna Dabrowska                ON A.page = C.page AND ( (C.user = ? AND C.ack > B.lastmod) )
23360ed3784SAnna Dabrowska                WHERE AUTH_ISMEMBER(A.assignee, ? , ?)
2348e55e483SAnna Dabrowska                AND ack IS NULL";
23574126d4bSAnna Dabrowska
2362541208bSAnna Dabrowska        $result = $sqlite->query($sql, $user, $user, implode('///', $groups));
23774126d4bSAnna Dabrowska        $assignments = $sqlite->res2arr($result);
23874126d4bSAnna Dabrowska        $sqlite->res_close($result);
23974126d4bSAnna Dabrowska
24074126d4bSAnna Dabrowska        return $assignments;
24174126d4bSAnna Dabrowska    }
24274126d4bSAnna Dabrowska
24374126d4bSAnna Dabrowska    /**
244863b6e48SAndreas Gohr     * Get all pages a user needs to acknowledge and the last acknowledge date
245d6011abdSAnna Dabrowska     *
246863b6e48SAndreas Gohr     * @param string $user
247863b6e48SAndreas Gohr     * @param array $groups
248d6011abdSAnna Dabrowska     * @return array|bool
249d6011abdSAnna Dabrowska     */
250863b6e48SAndreas Gohr    public function getUserAcknowledgements($user, $groups)
251d6011abdSAnna Dabrowska    {
252d6011abdSAnna Dabrowska        $sqlite = $this->getDB();
253d6011abdSAnna Dabrowska        if (!$sqlite) return false;
254d6011abdSAnna Dabrowska
255863b6e48SAndreas Gohr        $sql = "SELECT A.page, A.assignee, B.lastmod, C.user, MAX(C.ack) AS ack
256863b6e48SAndreas Gohr                  FROM assignments A
257863b6e48SAndreas Gohr                  JOIN pages B
258863b6e48SAndreas Gohr                    ON A.page = B.page
259863b6e48SAndreas Gohr             LEFT JOIN acks C
260863b6e48SAndreas Gohr                    ON A.page = C.page AND C.user = ?
261863b6e48SAndreas Gohr                 WHERE AUTH_ISMEMBER(A.assignee, ? , ?)
262863b6e48SAndreas Gohr            GROUP BY A.page
263863b6e48SAndreas Gohr            ORDER BY A.page
264863b6e48SAndreas Gohr            ";
265863b6e48SAndreas Gohr
266863b6e48SAndreas Gohr        $result = $sqlite->query($sql, $user, $user, implode('///', $groups));
267863b6e48SAndreas Gohr        $assignments = $sqlite->res2arr($result);
268863b6e48SAndreas Gohr        $sqlite->res_close($result);
269863b6e48SAndreas Gohr
270863b6e48SAndreas Gohr        return $assignments;
271863b6e48SAndreas Gohr    }
272863b6e48SAndreas Gohr
273863b6e48SAndreas Gohr    /**
274*c6d8c1d9SAndreas Gohr     * Resolve names of users assigned to a given page
275*c6d8c1d9SAndreas Gohr     *
276*c6d8c1d9SAndreas Gohr     * This can be slow on huge user bases!
277*c6d8c1d9SAndreas Gohr     *
278*c6d8c1d9SAndreas Gohr     * @param string $page
279*c6d8c1d9SAndreas Gohr     * @return array|false
280*c6d8c1d9SAndreas Gohr     */
281*c6d8c1d9SAndreas Gohr    public function getPageAssignees($page)
282*c6d8c1d9SAndreas Gohr    {
283*c6d8c1d9SAndreas Gohr        $sqlite = $this->getDB();
284*c6d8c1d9SAndreas Gohr        if (!$sqlite) return false;
285*c6d8c1d9SAndreas Gohr        /** @var AuthPlugin $auth */
286*c6d8c1d9SAndreas Gohr        global $auth;
287*c6d8c1d9SAndreas Gohr
288*c6d8c1d9SAndreas Gohr        $sql = "SELECT assignee
289*c6d8c1d9SAndreas Gohr                  FROM assignments
290*c6d8c1d9SAndreas Gohr                 WHERE page = ?";
291*c6d8c1d9SAndreas Gohr        $result = $sqlite->query($sql, $page);
292*c6d8c1d9SAndreas Gohr        $assignments = $sqlite->res2single($result);
293*c6d8c1d9SAndreas Gohr        $sqlite->res_close($result);
294*c6d8c1d9SAndreas Gohr
295*c6d8c1d9SAndreas Gohr        $users = [];
296*c6d8c1d9SAndreas Gohr        foreach (explode(',', $assignments) as $item) {
297*c6d8c1d9SAndreas Gohr            $item = trim($item);
298*c6d8c1d9SAndreas Gohr            if ($item === '') continue;
299*c6d8c1d9SAndreas Gohr            if ($item[0] == '@') {
300*c6d8c1d9SAndreas Gohr                $users = array_merge(
301*c6d8c1d9SAndreas Gohr                    $users,
302*c6d8c1d9SAndreas Gohr                    array_keys($auth->retrieveUsers(0, 0, ['grps' => substr($item, 1)]))
303*c6d8c1d9SAndreas Gohr                );
304*c6d8c1d9SAndreas Gohr            } else {
305*c6d8c1d9SAndreas Gohr                $users[] = $item;
306*c6d8c1d9SAndreas Gohr            }
307*c6d8c1d9SAndreas Gohr        }
308*c6d8c1d9SAndreas Gohr
309*c6d8c1d9SAndreas Gohr        return array_unique($users);
310*c6d8c1d9SAndreas Gohr    }
311*c6d8c1d9SAndreas Gohr
312*c6d8c1d9SAndreas Gohr    /**
313*c6d8c1d9SAndreas Gohr     * Get ack status for all assigned users of a given page
314*c6d8c1d9SAndreas Gohr     *
315*c6d8c1d9SAndreas Gohr     * This can be slow!
316*c6d8c1d9SAndreas Gohr     *
317*c6d8c1d9SAndreas Gohr     * @param string $page
318*c6d8c1d9SAndreas Gohr     * @return array|false
319*c6d8c1d9SAndreas Gohr     */
320*c6d8c1d9SAndreas Gohr    public function getPageAcknowledgements($page)
321*c6d8c1d9SAndreas Gohr    {
322*c6d8c1d9SAndreas Gohr        $users = $this->getPageAssignees($page);
323*c6d8c1d9SAndreas Gohr        if ($users === false) return false;
324*c6d8c1d9SAndreas Gohr        $sqlite = $this->getDB();
325*c6d8c1d9SAndreas Gohr        if (!$sqlite) return false;
326*c6d8c1d9SAndreas Gohr
327*c6d8c1d9SAndreas Gohr        $ulist = $sqlite->quote_and_join($users);
328*c6d8c1d9SAndreas Gohr        $sql = "SELECT A.page, A.lastmod, B.user, MAX(B.ack) AS ack
329*c6d8c1d9SAndreas Gohr                  FROM pages A
330*c6d8c1d9SAndreas Gohr             LEFT JOIN acks B
331*c6d8c1d9SAndreas Gohr                    ON A.page = B.page
332*c6d8c1d9SAndreas Gohr                   AND B.user IN ($ulist)
333*c6d8c1d9SAndreas Gohr                WHERE  A.page = ?
334*c6d8c1d9SAndreas Gohr              GROUP BY A.page, B.user
335*c6d8c1d9SAndreas Gohr                 ";
336*c6d8c1d9SAndreas Gohr        $result = $sqlite->query($sql, $page);
337*c6d8c1d9SAndreas Gohr        $acknowledgements = $sqlite->res2arr($result);
338*c6d8c1d9SAndreas Gohr        $sqlite->res_close($result);
339*c6d8c1d9SAndreas Gohr
340*c6d8c1d9SAndreas Gohr        // there should be at least one result, unless the page is unknown
341*c6d8c1d9SAndreas Gohr        if (!count($acknowledgements)) return false;
342*c6d8c1d9SAndreas Gohr
343*c6d8c1d9SAndreas Gohr        $baseinfo = [
344*c6d8c1d9SAndreas Gohr            'page' => $acknowledgements[0]['page'],
345*c6d8c1d9SAndreas Gohr            'lastmod' => $acknowledgements[0]['lastmod'],
346*c6d8c1d9SAndreas Gohr            'user' => null,
347*c6d8c1d9SAndreas Gohr            'ack' => null,
348*c6d8c1d9SAndreas Gohr        ];
349*c6d8c1d9SAndreas Gohr
350*c6d8c1d9SAndreas Gohr        // fill up the result with all users that never acknowledged the page
351*c6d8c1d9SAndreas Gohr        $combined = [];
352*c6d8c1d9SAndreas Gohr        foreach ($acknowledgements as $ack) {
353*c6d8c1d9SAndreas Gohr            if ($ack['user'] !== null) {
354*c6d8c1d9SAndreas Gohr                $combined[$ack['user']] = $ack;
355*c6d8c1d9SAndreas Gohr            }
356*c6d8c1d9SAndreas Gohr        }
357*c6d8c1d9SAndreas Gohr        foreach ($users as $user) {
358*c6d8c1d9SAndreas Gohr            if (!isset($combined[$user])) {
359*c6d8c1d9SAndreas Gohr                $combined[$user] = array_merge($baseinfo, ['user' => $user]);
360*c6d8c1d9SAndreas Gohr            }
361*c6d8c1d9SAndreas Gohr        }
362*c6d8c1d9SAndreas Gohr
363*c6d8c1d9SAndreas Gohr        ksort($combined);
364*c6d8c1d9SAndreas Gohr        return array_values($combined);
365*c6d8c1d9SAndreas Gohr    }
366*c6d8c1d9SAndreas Gohr
367*c6d8c1d9SAndreas Gohr    /**
368863b6e48SAndreas Gohr     * Returns all acknowledgements
369863b6e48SAndreas Gohr     *
370863b6e48SAndreas Gohr     * @param int $limit maximum number of results
371863b6e48SAndreas Gohr     * @return array|bool
372863b6e48SAndreas Gohr     */
373863b6e48SAndreas Gohr    public function getAcknowledgements($limit = 100)
374863b6e48SAndreas Gohr    {
375863b6e48SAndreas Gohr        $sqlite = $this->getDB();
376863b6e48SAndreas Gohr        if (!$sqlite) return false;
377863b6e48SAndreas Gohr
378863b6e48SAndreas Gohr        $sql = '
379863b6e48SAndreas Gohr            SELECT page, user, max(ack) AS ack
380863b6e48SAndreas Gohr              FROM acks
381863b6e48SAndreas Gohr          GROUP BY user,page
382863b6e48SAndreas Gohr          ORDER BY ack DESC
383863b6e48SAndreas Gohr             LIMIT ?
384863b6e48SAndreas Gohr              ';
385863b6e48SAndreas Gohr        $result = $sqlite->query($sql, $limit);
386d6011abdSAnna Dabrowska        $acknowledgements = $sqlite->res2arr($result);
387d6011abdSAnna Dabrowska        $sqlite->res_close($result);
388d6011abdSAnna Dabrowska
389d6011abdSAnna Dabrowska        return $acknowledgements;
390d6011abdSAnna Dabrowska    }
3914d6d17d0SAndreas Gohr}
3924d6d17d0SAndreas Gohr
393