xref: /plugin/acknowledge/helper.php (revision d6011abd6eaa661804c2dd0c81c94e7e9d027d66)
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
28cabb51d3SAndreas Gohr        return $sqlite;
29cabb51d3SAndreas Gohr    }
30cabb51d3SAndreas Gohr
31cabb51d3SAndreas Gohr    /**
32ef3ab392SAndreas Gohr     * Delete a page
33ef3ab392SAndreas Gohr     *
34ef3ab392SAndreas Gohr     * Cascades to delete all assigned data, etc.
35ef3ab392SAndreas Gohr     *
36ef3ab392SAndreas Gohr     * @param string $page Page ID
37ef3ab392SAndreas Gohr     */
38ef3ab392SAndreas Gohr    public function removePage($page)
39ef3ab392SAndreas Gohr    {
40ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
41ef3ab392SAndreas Gohr        if (!$sqlite) return;
42ef3ab392SAndreas Gohr
43ef3ab392SAndreas Gohr        $sql = "DELETE FROM pages WHERE page = ?";
44ef3ab392SAndreas Gohr        $sqlite->query($sql, $page);
45ef3ab392SAndreas Gohr    }
46ef3ab392SAndreas Gohr
47ef3ab392SAndreas Gohr    /**
48ef3ab392SAndreas Gohr     * Update last modified date of page
49ef3ab392SAndreas Gohr     *
50ef3ab392SAndreas Gohr     * @param string $page Page ID
51ef3ab392SAndreas Gohr     * @param int $lastmod timestamp of last non-minor change
52ef3ab392SAndreas Gohr     */
53ef3ab392SAndreas Gohr    public function storePageDate($page, $lastmod)
54ef3ab392SAndreas Gohr    {
55ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
56ef3ab392SAndreas Gohr        if (!$sqlite) return;
57ef3ab392SAndreas Gohr
58ef3ab392SAndreas Gohr        $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)";
59ef3ab392SAndreas Gohr        $sqlite->query($sql, $page, $lastmod);
60ef3ab392SAndreas Gohr    }
61ef3ab392SAndreas Gohr
62ef3ab392SAndreas Gohr    /**
63cabb51d3SAndreas Gohr     * @param string $page Page ID
64cabb51d3SAndreas Gohr     * @param string $assignees comma separated list of users and groups
65cabb51d3SAndreas Gohr     */
66cabb51d3SAndreas Gohr    public function setAssignees($page, $assignees)
67cabb51d3SAndreas Gohr    {
68cabb51d3SAndreas Gohr        $sqlite = $this->getDB();
69cabb51d3SAndreas Gohr        if (!$sqlite) return;
70cabb51d3SAndreas Gohr
71cabb51d3SAndreas Gohr        $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)";
72cabb51d3SAndreas Gohr        $sqlite->query($sql, $page, $assignees);
73cabb51d3SAndreas Gohr    }
74cabb51d3SAndreas Gohr
75ef3ab392SAndreas Gohr    /**
765773dd37SAnna Dabrowska     * Clears assignments for a page
77ef3ab392SAndreas Gohr     *
78ef3ab392SAndreas Gohr     * @param string $page Page ID
79ef3ab392SAndreas Gohr     */
80ef3ab392SAndreas Gohr    public function clearAssignments($page)
81ef3ab392SAndreas Gohr    {
82ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
83ef3ab392SAndreas Gohr        if (!$sqlite) return;
84cabb51d3SAndreas Gohr
85ef3ab392SAndreas Gohr        $sql = "DELETE FROM assignments WHERE page = ?";
86ef3ab392SAndreas Gohr        $sqlite->query($sql, $page);
87ef3ab392SAndreas Gohr    }
88ef3ab392SAndreas Gohr
89ef3ab392SAndreas Gohr
90ef3ab392SAndreas Gohr    /**
91ef3ab392SAndreas Gohr     * Is the given user one of the assignees for this page
92ef3ab392SAndreas Gohr     *
93ef3ab392SAndreas Gohr     * @param string $page Page ID
94ef3ab392SAndreas Gohr     * @param string $user user name to check
95ef3ab392SAndreas Gohr     * @param string[] $groups groups this user is in
96ef3ab392SAndreas Gohr     * @return bool
97ef3ab392SAndreas Gohr     */
98ef3ab392SAndreas Gohr    public function isUserAssigned($page, $user, $groups)
99ef3ab392SAndreas Gohr    {
100ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
101ef3ab392SAndreas Gohr        if (!$sqlite) return false;
102ef3ab392SAndreas Gohr
103ef3ab392SAndreas Gohr
104ef3ab392SAndreas Gohr        $sql = "SELECT assignee FROM assignments WHERE page = ?";
105ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page);
106ef3ab392SAndreas Gohr        $assignees = (string)$sqlite->res2single($result);
107ef3ab392SAndreas Gohr        $sqlite->res_close($result);
108ef3ab392SAndreas Gohr
109ef3ab392SAndreas Gohr        return auth_isMember($assignees, $user, $groups);
110ef3ab392SAndreas Gohr    }
111ef3ab392SAndreas Gohr
112ef3ab392SAndreas Gohr    /**
113ef3ab392SAndreas Gohr     * Has the given user acknowledged the given page?
114ef3ab392SAndreas Gohr     *
115ef3ab392SAndreas Gohr     * @param string $page
116ef3ab392SAndreas Gohr     * @param string $user
1175773dd37SAnna Dabrowska     * @return bool|int timestamp of acknowledgement or false
118ef3ab392SAndreas Gohr     */
119ef3ab392SAndreas Gohr    public function hasUserAcknowledged($page, $user)
120ef3ab392SAndreas Gohr    {
121ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
122ef3ab392SAndreas Gohr        if (!$sqlite) return false;
123ef3ab392SAndreas Gohr
124ef3ab392SAndreas Gohr        $sql = "SELECT ack
125ef3ab392SAndreas Gohr                  FROM acks A, pages B
126ef3ab392SAndreas Gohr                 WHERE A.page = B.page
1275773dd37SAnna Dabrowska                   AND A.page = ?
1285773dd37SAnna Dabrowska                   AND A.user = ?
129ef3ab392SAndreas Gohr                   AND A.ack >= B.lastmod";
130ef3ab392SAndreas Gohr
131ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page, $user);
132ef3ab392SAndreas Gohr        $acktime = $sqlite->res2single($result);
133ef3ab392SAndreas Gohr        $sqlite->res_close($result);
134ef3ab392SAndreas Gohr
135ef3ab392SAndreas Gohr        return $acktime ? (int)$acktime : false;
136ef3ab392SAndreas Gohr    }
1375773dd37SAnna Dabrowska
1385773dd37SAnna Dabrowska    /**
1395773dd37SAnna Dabrowska     * Save user's acknowledgement for a given page
1405773dd37SAnna Dabrowska     *
1415773dd37SAnna Dabrowska     * @param string $page
1425773dd37SAnna Dabrowska     * @param string $user
1435773dd37SAnna Dabrowska     * @return bool
1445773dd37SAnna Dabrowska     */
1455773dd37SAnna Dabrowska    public function saveAcknowledgement($page, $user)
1465773dd37SAnna Dabrowska    {
1475773dd37SAnna Dabrowska        $sqlite = $this->getDB();
1485773dd37SAnna Dabrowska        if (!$sqlite) return false;
1495773dd37SAnna Dabrowska
1505773dd37SAnna Dabrowska        $sql = "REPLACE INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))";
1515773dd37SAnna Dabrowska
1525773dd37SAnna Dabrowska        $result = $sqlite->query($sql, $page, $user);
1535773dd37SAnna Dabrowska        $sqlite->res_close($result);
1545773dd37SAnna Dabrowska        return true;
1555773dd37SAnna Dabrowska
1565773dd37SAnna Dabrowska    }
15774126d4bSAnna Dabrowska
15874126d4bSAnna Dabrowska    /**
15974126d4bSAnna Dabrowska     * Fetch all assignments for a given user, with additional page information.
16074126d4bSAnna Dabrowska     *
16174126d4bSAnna Dabrowska     * @param string $user
16274126d4bSAnna Dabrowska     * @return array|bool
16374126d4bSAnna Dabrowska     */
16474126d4bSAnna Dabrowska    public function getUserAssignments($user)
16574126d4bSAnna Dabrowska    {
16674126d4bSAnna Dabrowska        $sqlite = $this->getDB();
16774126d4bSAnna Dabrowska        if (!$sqlite) return false;
16874126d4bSAnna Dabrowska
16974126d4bSAnna Dabrowska        global $USERINFO;
17074126d4bSAnna Dabrowska        $groups = $USERINFO['grps'];
17174126d4bSAnna Dabrowska
17274126d4bSAnna Dabrowska        $sql = "SELECT * FROM assignments A
17374126d4bSAnna Dabrowska                JOIN pages B
17474126d4bSAnna Dabrowska                ON A.page = B.page
17574126d4bSAnna Dabrowska                WHERE A.assignee LIKE ? OR A.assignee LIKE ?";
17674126d4bSAnna Dabrowska
17774126d4bSAnna Dabrowska        $userWildcard = '%' . $user . '%';
17874126d4bSAnna Dabrowska        $groupWildcard = '%@' . $groups . '%';
17974126d4bSAnna Dabrowska
18074126d4bSAnna Dabrowska        $result = $sqlite->query($sql, $userWildcard, $groupWildcard);
18174126d4bSAnna Dabrowska        $assignments = $sqlite->res2arr($result);
18274126d4bSAnna Dabrowska        $sqlite->res_close($result);
18374126d4bSAnna Dabrowska
18474126d4bSAnna Dabrowska        return $assignments;
18574126d4bSAnna Dabrowska    }
18674126d4bSAnna Dabrowska
18774126d4bSAnna Dabrowska    /**
18874126d4bSAnna Dabrowska     * Compare user's assignments with their past acknowledgements and return only pages
18974126d4bSAnna Dabrowska     * without or with outdated acknowledgements
19074126d4bSAnna Dabrowska     *
19174126d4bSAnna Dabrowska     * @param string $user
19274126d4bSAnna Dabrowska     * @param array $assignments
19374126d4bSAnna Dabrowska     * @return array|bool
19474126d4bSAnna Dabrowska     */
19574126d4bSAnna Dabrowska    public function filterAcknowledged($user, $assignments)
19674126d4bSAnna Dabrowska    {
19774126d4bSAnna Dabrowska        $sqlite = $this->getDB();
19874126d4bSAnna Dabrowska        if (!$sqlite) return false;
19974126d4bSAnna Dabrowska
20074126d4bSAnna Dabrowska        $sql = 'SELECT * FROM acks WHERE user = ?';
20174126d4bSAnna Dabrowska        $result = $sqlite->query($sql, $user);
20274126d4bSAnna Dabrowska        $acknowledgements = $sqlite->res2arr($result);
20374126d4bSAnna Dabrowska        $sqlite->res_close($result);
20474126d4bSAnna Dabrowska
20574126d4bSAnna Dabrowska        $listing = [];
20674126d4bSAnna Dabrowska        $pageAcks = array_column($acknowledgements, 'ack', 'page');
20774126d4bSAnna Dabrowska        foreach ($assignments as $assignment) {
20874126d4bSAnna Dabrowska            if (
20974126d4bSAnna Dabrowska                !in_array($assignment['page'], array_keys($pageAcks))
21074126d4bSAnna Dabrowska                || (int)$assignment['lastmod'] > (int)$pageAcks[$assignment['page']]
21174126d4bSAnna Dabrowska            ) {
21274126d4bSAnna Dabrowska                $listing[] = $assignment;
21374126d4bSAnna Dabrowska            }
21474126d4bSAnna Dabrowska        }
21574126d4bSAnna Dabrowska
21674126d4bSAnna Dabrowska        return $listing;
21774126d4bSAnna Dabrowska    }
218*d6011abdSAnna Dabrowska
219*d6011abdSAnna Dabrowska    /**
220*d6011abdSAnna Dabrowska     * Returns all acknowledgements
221*d6011abdSAnna Dabrowska     *
222*d6011abdSAnna Dabrowska     * @return array|bool
223*d6011abdSAnna Dabrowska     */
224*d6011abdSAnna Dabrowska    public function getAcknowledgements()
225*d6011abdSAnna Dabrowska    {
226*d6011abdSAnna Dabrowska        $sqlite = $this->getDB();
227*d6011abdSAnna Dabrowska        if (!$sqlite) return false;
228*d6011abdSAnna Dabrowska
229*d6011abdSAnna Dabrowska        $sql = 'SELECT * FROM acks ORDER BY ack DESC';
230*d6011abdSAnna Dabrowska        $result = $sqlite->query($sql);
231*d6011abdSAnna Dabrowska        $acknowledgements = $sqlite->res2arr($result);
232*d6011abdSAnna Dabrowska        $sqlite->res_close($result);
233*d6011abdSAnna Dabrowska
234*d6011abdSAnna Dabrowska        return $acknowledgements;
235*d6011abdSAnna Dabrowska    }
2364d6d17d0SAndreas Gohr}
2374d6d17d0SAndreas Gohr
238