xref: /plugin/acknowledge/helper.php (revision 9c3eae1e3c610e8434228ea1685aff223b6828aa)
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
28*9c3eae1eSAnna Dabrowska        $this->registerUDF($sqlite);
29*9c3eae1eSAnna Dabrowska
30cabb51d3SAndreas Gohr        return $sqlite;
31cabb51d3SAndreas Gohr    }
32cabb51d3SAndreas Gohr
33cabb51d3SAndreas Gohr    /**
34*9c3eae1eSAnna Dabrowska     * Register user defined functions
35*9c3eae1eSAnna Dabrowska     *
36*9c3eae1eSAnna Dabrowska     * @param helper_plugin_sqlite $sqlite
37*9c3eae1eSAnna Dabrowska     */
38*9c3eae1eSAnna Dabrowska    protected function registerUDF($sqlite)
39*9c3eae1eSAnna Dabrowska    {
40*9c3eae1eSAnna Dabrowska        $sqlite->create_function('AUTH_ISMEMBER', [$this, 'auth_isMember'], -1);
41*9c3eae1eSAnna Dabrowska    }
42*9c3eae1eSAnna Dabrowska
43*9c3eae1eSAnna Dabrowska    /**
44*9c3eae1eSAnna Dabrowska     * Wrapper function for auth_isMember which accepts groups as string
45*9c3eae1eSAnna Dabrowska     *
46*9c3eae1eSAnna Dabrowska     * @param string $memberList
47*9c3eae1eSAnna Dabrowska     * @param string $user
48*9c3eae1eSAnna Dabrowska     * @param string $groups
49*9c3eae1eSAnna Dabrowska     * @return bool
50*9c3eae1eSAnna Dabrowska     */
51*9c3eae1eSAnna Dabrowska    public function auth_isMember($memberList, $user, $groups)
52*9c3eae1eSAnna Dabrowska    {
53*9c3eae1eSAnna Dabrowska        $a = 1;
54*9c3eae1eSAnna Dabrowska        return auth_isMember($memberList, $user, explode(',', $groups));
55*9c3eae1eSAnna Dabrowska    }
56*9c3eae1eSAnna Dabrowska
57*9c3eae1eSAnna 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    /**
74ef3ab392SAndreas Gohr     * Update last modified date of page
75ef3ab392SAndreas Gohr     *
76ef3ab392SAndreas Gohr     * @param string $page Page ID
77ef3ab392SAndreas Gohr     * @param int $lastmod timestamp of last non-minor change
78ef3ab392SAndreas Gohr     */
79ef3ab392SAndreas Gohr    public function storePageDate($page, $lastmod)
80ef3ab392SAndreas Gohr    {
81ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
82ef3ab392SAndreas Gohr        if (!$sqlite) return;
83ef3ab392SAndreas Gohr
84ef3ab392SAndreas Gohr        $sql = "REPLACE INTO pages (page, lastmod) VALUES (?,?)";
85ef3ab392SAndreas Gohr        $sqlite->query($sql, $page, $lastmod);
86ef3ab392SAndreas Gohr    }
87ef3ab392SAndreas Gohr
88ef3ab392SAndreas Gohr    /**
89cabb51d3SAndreas Gohr     * @param string $page Page ID
90cabb51d3SAndreas Gohr     * @param string $assignees comma separated list of users and groups
91cabb51d3SAndreas Gohr     */
92cabb51d3SAndreas Gohr    public function setAssignees($page, $assignees)
93cabb51d3SAndreas Gohr    {
94cabb51d3SAndreas Gohr        $sqlite = $this->getDB();
95cabb51d3SAndreas Gohr        if (!$sqlite) return;
96cabb51d3SAndreas Gohr
97cabb51d3SAndreas Gohr        $sql = "REPLACE INTO assignments ('page', 'assignee') VALUES (?,?)";
98cabb51d3SAndreas Gohr        $sqlite->query($sql, $page, $assignees);
99cabb51d3SAndreas Gohr    }
100cabb51d3SAndreas Gohr
101ef3ab392SAndreas Gohr    /**
1025773dd37SAnna Dabrowska     * Clears assignments for a page
103ef3ab392SAndreas Gohr     *
104ef3ab392SAndreas Gohr     * @param string $page Page ID
105ef3ab392SAndreas Gohr     */
106ef3ab392SAndreas Gohr    public function clearAssignments($page)
107ef3ab392SAndreas Gohr    {
108ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
109ef3ab392SAndreas Gohr        if (!$sqlite) return;
110cabb51d3SAndreas Gohr
111ef3ab392SAndreas Gohr        $sql = "DELETE FROM assignments WHERE page = ?";
112ef3ab392SAndreas Gohr        $sqlite->query($sql, $page);
113ef3ab392SAndreas Gohr    }
114ef3ab392SAndreas Gohr
115ef3ab392SAndreas Gohr
116ef3ab392SAndreas Gohr    /**
117ef3ab392SAndreas Gohr     * Is the given user one of the assignees for this page
118ef3ab392SAndreas Gohr     *
119ef3ab392SAndreas Gohr     * @param string $page Page ID
120ef3ab392SAndreas Gohr     * @param string $user user name to check
121ef3ab392SAndreas Gohr     * @param string[] $groups groups this user is in
122ef3ab392SAndreas Gohr     * @return bool
123ef3ab392SAndreas Gohr     */
124ef3ab392SAndreas Gohr    public function isUserAssigned($page, $user, $groups)
125ef3ab392SAndreas Gohr    {
126ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
127ef3ab392SAndreas Gohr        if (!$sqlite) return false;
128ef3ab392SAndreas Gohr
129ef3ab392SAndreas Gohr
130ef3ab392SAndreas Gohr        $sql = "SELECT assignee FROM assignments WHERE page = ?";
131ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page);
132ef3ab392SAndreas Gohr        $assignees = (string)$sqlite->res2single($result);
133ef3ab392SAndreas Gohr        $sqlite->res_close($result);
134ef3ab392SAndreas Gohr
135ef3ab392SAndreas Gohr        return auth_isMember($assignees, $user, $groups);
136ef3ab392SAndreas Gohr    }
137ef3ab392SAndreas Gohr
138ef3ab392SAndreas Gohr    /**
139ef3ab392SAndreas Gohr     * Has the given user acknowledged the given page?
140ef3ab392SAndreas Gohr     *
141ef3ab392SAndreas Gohr     * @param string $page
142ef3ab392SAndreas Gohr     * @param string $user
1435773dd37SAnna Dabrowska     * @return bool|int timestamp of acknowledgement or false
144ef3ab392SAndreas Gohr     */
145ef3ab392SAndreas Gohr    public function hasUserAcknowledged($page, $user)
146ef3ab392SAndreas Gohr    {
147ef3ab392SAndreas Gohr        $sqlite = $this->getDB();
148ef3ab392SAndreas Gohr        if (!$sqlite) return false;
149ef3ab392SAndreas Gohr
150ef3ab392SAndreas Gohr        $sql = "SELECT ack
151ef3ab392SAndreas Gohr                  FROM acks A, pages B
152ef3ab392SAndreas Gohr                 WHERE A.page = B.page
1535773dd37SAnna Dabrowska                   AND A.page = ?
1545773dd37SAnna Dabrowska                   AND A.user = ?
155ef3ab392SAndreas Gohr                   AND A.ack >= B.lastmod";
156ef3ab392SAndreas Gohr
157ef3ab392SAndreas Gohr        $result = $sqlite->query($sql, $page, $user);
158ef3ab392SAndreas Gohr        $acktime = $sqlite->res2single($result);
159ef3ab392SAndreas Gohr        $sqlite->res_close($result);
160ef3ab392SAndreas Gohr
161ef3ab392SAndreas Gohr        return $acktime ? (int)$acktime : false;
162ef3ab392SAndreas Gohr    }
1635773dd37SAnna Dabrowska
1645773dd37SAnna Dabrowska    /**
1655773dd37SAnna Dabrowska     * Save user's acknowledgement for a given page
1665773dd37SAnna Dabrowska     *
1675773dd37SAnna Dabrowska     * @param string $page
1685773dd37SAnna Dabrowska     * @param string $user
1695773dd37SAnna Dabrowska     * @return bool
1705773dd37SAnna Dabrowska     */
1715773dd37SAnna Dabrowska    public function saveAcknowledgement($page, $user)
1725773dd37SAnna Dabrowska    {
1735773dd37SAnna Dabrowska        $sqlite = $this->getDB();
1745773dd37SAnna Dabrowska        if (!$sqlite) return false;
1755773dd37SAnna Dabrowska
1765773dd37SAnna Dabrowska        $sql = "REPLACE INTO acks (page, user, ack) VALUES (?,?, strftime('%s','now'))";
1775773dd37SAnna Dabrowska
1785773dd37SAnna Dabrowska        $result = $sqlite->query($sql, $page, $user);
1795773dd37SAnna Dabrowska        $sqlite->res_close($result);
1805773dd37SAnna Dabrowska        return true;
1815773dd37SAnna Dabrowska
1825773dd37SAnna Dabrowska    }
18374126d4bSAnna Dabrowska
18474126d4bSAnna Dabrowska    /**
18574126d4bSAnna Dabrowska     * Fetch all assignments for a given user, with additional page information.
18674126d4bSAnna Dabrowska     *
18774126d4bSAnna Dabrowska     * @param string $user
18874126d4bSAnna Dabrowska     * @return array|bool
18974126d4bSAnna Dabrowska     */
19074126d4bSAnna Dabrowska    public function getUserAssignments($user)
19174126d4bSAnna Dabrowska    {
19274126d4bSAnna Dabrowska        $sqlite = $this->getDB();
19374126d4bSAnna Dabrowska        if (!$sqlite) return false;
19474126d4bSAnna Dabrowska
19574126d4bSAnna Dabrowska        global $USERINFO;
19674126d4bSAnna Dabrowska        $groups = $USERINFO['grps'];
19774126d4bSAnna Dabrowska
19874126d4bSAnna Dabrowska        $sql = "SELECT * FROM assignments A
19974126d4bSAnna Dabrowska                JOIN pages B
20074126d4bSAnna Dabrowska                ON A.page = B.page
201*9c3eae1eSAnna Dabrowska                WHERE AUTH_ISMEMBER(A.assignee, ? , ?)";
20274126d4bSAnna Dabrowska
203*9c3eae1eSAnna Dabrowska        $result = $sqlite->query($sql, $user, implode(',', $groups));
20474126d4bSAnna Dabrowska        $assignments = $sqlite->res2arr($result);
20574126d4bSAnna Dabrowska        $sqlite->res_close($result);
20674126d4bSAnna Dabrowska
20774126d4bSAnna Dabrowska        return $assignments;
20874126d4bSAnna Dabrowska    }
20974126d4bSAnna Dabrowska
21074126d4bSAnna Dabrowska    /**
21174126d4bSAnna Dabrowska     * Compare user's assignments with their past acknowledgements and return only pages
21274126d4bSAnna Dabrowska     * without or with outdated acknowledgements
21374126d4bSAnna Dabrowska     *
21474126d4bSAnna Dabrowska     * @param string $user
21574126d4bSAnna Dabrowska     * @param array $assignments
21674126d4bSAnna Dabrowska     * @return array|bool
21774126d4bSAnna Dabrowska     */
21874126d4bSAnna Dabrowska    public function filterAcknowledged($user, $assignments)
21974126d4bSAnna Dabrowska    {
22074126d4bSAnna Dabrowska        $sqlite = $this->getDB();
22174126d4bSAnna Dabrowska        if (!$sqlite) return false;
22274126d4bSAnna Dabrowska
22374126d4bSAnna Dabrowska        $sql = 'SELECT * FROM acks WHERE user = ?';
22474126d4bSAnna Dabrowska        $result = $sqlite->query($sql, $user);
22574126d4bSAnna Dabrowska        $acknowledgements = $sqlite->res2arr($result);
22674126d4bSAnna Dabrowska        $sqlite->res_close($result);
22774126d4bSAnna Dabrowska
22874126d4bSAnna Dabrowska        $listing = [];
22974126d4bSAnna Dabrowska        $pageAcks = array_column($acknowledgements, 'ack', 'page');
23074126d4bSAnna Dabrowska        foreach ($assignments as $assignment) {
23174126d4bSAnna Dabrowska            if (
23274126d4bSAnna Dabrowska                !in_array($assignment['page'], array_keys($pageAcks))
23374126d4bSAnna Dabrowska                || (int)$assignment['lastmod'] > (int)$pageAcks[$assignment['page']]
23474126d4bSAnna Dabrowska            ) {
23574126d4bSAnna Dabrowska                $listing[] = $assignment;
23674126d4bSAnna Dabrowska            }
23774126d4bSAnna Dabrowska        }
23874126d4bSAnna Dabrowska
23974126d4bSAnna Dabrowska        return $listing;
24074126d4bSAnna Dabrowska    }
241d6011abdSAnna Dabrowska
242d6011abdSAnna Dabrowska    /**
243d6011abdSAnna Dabrowska     * Returns all acknowledgements
244d6011abdSAnna Dabrowska     *
245d6011abdSAnna Dabrowska     * @return array|bool
246d6011abdSAnna Dabrowska     */
247d6011abdSAnna Dabrowska    public function getAcknowledgements()
248d6011abdSAnna Dabrowska    {
249d6011abdSAnna Dabrowska        $sqlite = $this->getDB();
250d6011abdSAnna Dabrowska        if (!$sqlite) return false;
251d6011abdSAnna Dabrowska
252d6011abdSAnna Dabrowska        $sql = 'SELECT * FROM acks ORDER BY ack DESC';
253d6011abdSAnna Dabrowska        $result = $sqlite->query($sql);
254d6011abdSAnna Dabrowska        $acknowledgements = $sqlite->res2arr($result);
255d6011abdSAnna Dabrowska        $sqlite->res_close($result);
256d6011abdSAnna Dabrowska
257d6011abdSAnna Dabrowska        return $acknowledgements;
258d6011abdSAnna Dabrowska    }
2594d6d17d0SAndreas Gohr}
2604d6d17d0SAndreas Gohr
261