xref: /plugin/structpublish/helper/db.php (revision fbeca28f07645ee7be59a99bf4f2014a3c2537d3)
1<?php
2
3use dokuwiki\plugin\structpublish\meta\Assignments;
4
5class helper_plugin_structpublish_db extends DokuWiki_Plugin
6{
7    protected $initialized = false;
8
9    /**
10     * Access the struct database
11     *
12     * Registers our own IS_PUBLISHER function with sqlite
13     *
14     * @return \dokuwiki\plugin\sqlite\SQLiteDB|null
15     */
16    public function getDB()
17    {
18        /** @var helper_plugin_struct_db $struct */
19        $struct = plugin_load('helper', 'struct_db');
20        if(!$struct) {
21            // FIXME show message?
22            return null;
23        }
24        $sqlite = $struct->getDB(false);
25        if(!$sqlite) return null;
26
27        // on init
28        if(!$this->initialized) {
29            $sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'isPublisher'], -1);
30            $this->initialized = true;
31        }
32
33        return $sqlite;
34    }
35
36    /**
37     * Get list of all pages known to the plugin
38     * @return array
39     */
40    public function getPages()
41    {
42        $sqlite = $this->getDB();
43        if(!$sqlite) return [];
44
45        $sql = 'SELECT pid FROM titles';
46        $list = $sqlite->queryAll($sql);
47        return array_column($list, 'pid');
48    }
49
50    /**
51     * Returns true if the current page is included in publishing workflows
52     *
53     * @return bool
54     */
55    public function isPublishable()
56    {
57        global $ID;
58        $sqlite = $this->getDB();
59        if(!$sqlite) return false;
60
61        $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1';
62        return (bool) $sqlite->queryAll($sql, $ID);
63    }
64
65    /**
66     * Check if the current user has the given roles on the current page
67     *
68     * @param string $pid The page ID to check access for
69     * @param string[] $roles Roles needed. Empty for any role
70     * @return bool
71     */
72    public function checkAccess($pid, $roles = [])
73    {
74        return self::userHasRole($pid, '', [], $roles);
75    }
76
77    /**
78     * Function registered in SQLite
79     *
80     * Params are read via function args
81     *
82     * @param ...string $pid, $userId, $groups...
83     * @return int Return an integer instead of boolean for better sqlite compatibility
84     */
85    public function isPublisher()
86    {
87        if (!$this->isPublishable()) return 1;
88
89        global $USERINFO;
90        global $INPUT;
91
92        $args = func_get_args();
93        $pid = $args[0];
94        $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER');
95        $grps = $args[2] ?? ($USERINFO['grps'] ?? []);
96
97        return (int)$this->userHasRole(
98            $pid,
99            $userId,
100            $grps
101        );
102    }
103
104    /**
105     * Check if a given user has role assignment for a given page
106     *
107     * @param string $pid Page to check
108     * @param string $userId User login name, current user if empty
109     * @param string[] $grps Groups the user has, current user's groups if empty user
110     * @param string[] $roles Roles the user should have, empty for any role
111     * @return bool
112     */
113    public static function userHasRole($pid, $userId = '', $grps = [], $roles = [])
114    {
115        global $INPUT;
116        global $USERINFO;
117
118        if (blank($userId)) {
119            $userId = $INPUT->server->str('REMOTE_USER');
120            $grps = $USERINFO['grps'] ?? [];
121        }
122
123        $assignments = Assignments::getInstance();
124        $rules = $assignments->getPageAssignments($pid);
125
126        // if no roles are given, any role is fine
127        if (empty($roles)) {
128            return auth_isMember(
129                implode(',', array_merge(...array_values($rules))),
130                $userId,
131                $grps
132            );
133        }
134
135        foreach ($roles as $role) {
136            if (isset($rules[$role])) {
137                $users = $rules[$role];
138                if (auth_isMember(implode(',', $users), $userId, $grps)) {
139                    return true;
140                }
141            }
142        }
143
144        return false;
145    }
146
147}
148