xref: /plugin/structpublish/helper/db.php (revision ed00f27d283750104fb7f80bdad97cf3156c4d59)
1e394901aSAnna Dabrowska<?php
2e394901aSAnna Dabrowska
3*ed00f27dSAndreas Gohruse dokuwiki\plugin\structpublish\meta\Assignments;
4*ed00f27dSAndreas Gohr
5*ed00f27dSAndreas Gohr/**
6*ed00f27dSAndreas Gohr * @todo by extending helper_plugin_struct_db we break the singlton pattern and have two database connections
7*ed00f27dSAndreas Gohr */
8e394901aSAnna Dabrowskaclass helper_plugin_structpublish_db extends helper_plugin_struct_db
9e394901aSAnna Dabrowska{
10*ed00f27dSAndreas Gohr    /** @inheritdoc */
11*ed00f27dSAndreas Gohr    protected function init()
12*ed00f27dSAndreas Gohr    {
13*ed00f27dSAndreas Gohr        parent::init();
14*ed00f27dSAndreas Gohr        if ($this->sqlite) {
15*ed00f27dSAndreas Gohr            $this->sqlite->create_function('IS_PUBLISHER', [$this, 'isPublisher'], -1);
16*ed00f27dSAndreas Gohr        }
17*ed00f27dSAndreas Gohr    }
18939e6e3cSAnna Dabrowska
19e394901aSAnna Dabrowska    /**
20910e7e15SAnna Dabrowska     * Get list of all pages known to the plugin
21910e7e15SAnna Dabrowska     * @return array
22910e7e15SAnna Dabrowska     */
23126b0b8eSAnna Dabrowska    public function getPages()
24910e7e15SAnna Dabrowska    {
25126b0b8eSAnna Dabrowska        $sql = 'SELECT pid FROM titles';
26126b0b8eSAnna Dabrowska        $res = $this->sqlite->query($sql);
27910e7e15SAnna Dabrowska        $list = $this->sqlite->res2arr($res);
28910e7e15SAnna Dabrowska        $this->sqlite->res_close($res);
29126b0b8eSAnna Dabrowska        return array_column($list, 'pid');
30910e7e15SAnna Dabrowska    }
31910e7e15SAnna Dabrowska
32910e7e15SAnna Dabrowska    /**
33939e6e3cSAnna Dabrowska     * Returns true if the current page is included in publishing workflows
34939e6e3cSAnna Dabrowska     *
35939e6e3cSAnna Dabrowska     * @return bool
36939e6e3cSAnna Dabrowska     */
37939e6e3cSAnna Dabrowska    public function isPublishable()
38939e6e3cSAnna Dabrowska    {
39939e6e3cSAnna Dabrowska        global $ID;
40939e6e3cSAnna Dabrowska
41126b0b8eSAnna Dabrowska        $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1';
42939e6e3cSAnna Dabrowska        $res = $this->sqlite->query($sql, $ID);
43939e6e3cSAnna Dabrowska        if ($res && $this->sqlite->res2count($res)) {
44939e6e3cSAnna Dabrowska            return true;
45939e6e3cSAnna Dabrowska        }
46939e6e3cSAnna Dabrowska        return false;
47939e6e3cSAnna Dabrowska    }
482b546eccSAndreas Gohr
492b546eccSAndreas Gohr    /**
502b546eccSAndreas Gohr     * Check if the current user has the given roles on the current page
512b546eccSAndreas Gohr     *
522b546eccSAndreas Gohr     * @param string $pid The page ID to check access for
532b546eccSAndreas Gohr     * @param string[] $roles Roles needed. Empty for any role
542b546eccSAndreas Gohr     * @return bool
552b546eccSAndreas Gohr     */
562b546eccSAndreas Gohr    public function checkAccess($pid, $roles = [])
572b546eccSAndreas Gohr    {
58*ed00f27dSAndreas Gohr        return self::userHasRole($pid, '', [], $roles);
59*ed00f27dSAndreas Gohr    }
60*ed00f27dSAndreas Gohr
61*ed00f27dSAndreas Gohr    /**
62*ed00f27dSAndreas Gohr     * Function registered in SQLite
63*ed00f27dSAndreas Gohr     *
64*ed00f27dSAndreas Gohr     * Params are read via function args
65*ed00f27dSAndreas Gohr     *
66*ed00f27dSAndreas Gohr     * @param ...string $pid, $userId, $groups...
67*ed00f27dSAndreas Gohr     * @return int Return an integer instead of boolean for better sqlite compatibility
68*ed00f27dSAndreas Gohr     */
69*ed00f27dSAndreas Gohr    public function isPublisher()
70*ed00f27dSAndreas Gohr    {
71*ed00f27dSAndreas Gohr        if (!$this->isPublishable()) return 1;
72*ed00f27dSAndreas Gohr
73*ed00f27dSAndreas Gohr        global $USERINFO;
74*ed00f27dSAndreas Gohr        global $INPUT;
75*ed00f27dSAndreas Gohr
76*ed00f27dSAndreas Gohr        $args = func_get_args();
77*ed00f27dSAndreas Gohr        $pid = $args[0];
78*ed00f27dSAndreas Gohr        $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER');
79*ed00f27dSAndreas Gohr        $grps = $args[2] ?? ($USERINFO['grps'] ?? []);
80*ed00f27dSAndreas Gohr
81*ed00f27dSAndreas Gohr        return (int)$this->userHasRole(
82*ed00f27dSAndreas Gohr            $pid,
83*ed00f27dSAndreas Gohr            $userId,
84*ed00f27dSAndreas Gohr            $grps
85*ed00f27dSAndreas Gohr        );
86*ed00f27dSAndreas Gohr    }
87*ed00f27dSAndreas Gohr
88*ed00f27dSAndreas Gohr    /**
89*ed00f27dSAndreas Gohr     * Check if a given user has role assignment for a given page
90*ed00f27dSAndreas Gohr     *
91*ed00f27dSAndreas Gohr     * @param string $pid Page to check
92*ed00f27dSAndreas Gohr     * @param string $userId User login name, current user if empty
93*ed00f27dSAndreas Gohr     * @param string[] $grps Groups the user has, current user's groups if empty user
94*ed00f27dSAndreas Gohr     * @param string[] $roles Roles the user should have, empty for any role
95*ed00f27dSAndreas Gohr     * @return bool
96*ed00f27dSAndreas Gohr     */
97*ed00f27dSAndreas Gohr    public static function userHasRole($pid, $userId = '', $grps = [], $roles = [])
98*ed00f27dSAndreas Gohr    {
99*ed00f27dSAndreas Gohr        global $INPUT;
100*ed00f27dSAndreas Gohr        global $USERINFO;
101*ed00f27dSAndreas Gohr
102*ed00f27dSAndreas Gohr        if (blank($userId)) {
103*ed00f27dSAndreas Gohr            $userId = $INPUT->server->str('REMOTE_USER');
104*ed00f27dSAndreas Gohr            $grps = $USERINFO['grps'] ?? [];
105*ed00f27dSAndreas Gohr        }
106*ed00f27dSAndreas Gohr
107*ed00f27dSAndreas Gohr        $assignments = Assignments::getInstance();
108*ed00f27dSAndreas Gohr        $rules = $assignments->getPageAssignments($pid);
109*ed00f27dSAndreas Gohr
110*ed00f27dSAndreas Gohr        // if no roles are given, any role is fine
111*ed00f27dSAndreas Gohr        if (empty($roles)) {
112*ed00f27dSAndreas Gohr            return auth_isMember(
113*ed00f27dSAndreas Gohr                implode(',', array_merge(...array_values($rules))),
114*ed00f27dSAndreas Gohr                $userId,
115*ed00f27dSAndreas Gohr                $grps
116*ed00f27dSAndreas Gohr            );
117*ed00f27dSAndreas Gohr        }
118*ed00f27dSAndreas Gohr
119*ed00f27dSAndreas Gohr        foreach ($roles as $role) {
120*ed00f27dSAndreas Gohr            if (isset($rules[$role])) {
121*ed00f27dSAndreas Gohr                $users = $rules[$role];
122*ed00f27dSAndreas Gohr                if (auth_isMember(implode(',', $users), $userId, $grps)) {
123*ed00f27dSAndreas Gohr                    return true;
124*ed00f27dSAndreas Gohr                }
125*ed00f27dSAndreas Gohr            }
126*ed00f27dSAndreas Gohr        }
127*ed00f27dSAndreas Gohr
128*ed00f27dSAndreas Gohr        return false;
1292b546eccSAndreas Gohr    }
1302b546eccSAndreas Gohr
131e394901aSAnna Dabrowska}
132