xref: /plugin/structpublish/helper/db.php (revision 5b1fd00b9f767f78b08ea3240adf8c1fe925892a)
1e394901aSAnna Dabrowska<?php
2e394901aSAnna Dabrowska
3ed00f27dSAndreas Gohruse dokuwiki\plugin\structpublish\meta\Assignments;
4ed00f27dSAndreas Gohr
5*5b1fd00bSAndreas Gohrclass helper_plugin_structpublish_db extends DokuWiki_Plugin
6*5b1fd00bSAndreas Gohr{
7*5b1fd00bSAndreas Gohr    protected $initialized = false;
8*5b1fd00bSAndreas Gohr
9ed00f27dSAndreas Gohr    /**
10*5b1fd00bSAndreas Gohr     * Access the struct database
11*5b1fd00bSAndreas Gohr     *
12*5b1fd00bSAndreas Gohr     * Registers our own IS_PUBLISHER function with sqlite
13*5b1fd00bSAndreas Gohr     *
14*5b1fd00bSAndreas Gohr     * @return \dokuwiki\plugin\sqlite\SQLiteDB|null
15ed00f27dSAndreas Gohr     */
16*5b1fd00bSAndreas Gohr    public function getDB()
17e394901aSAnna Dabrowska    {
18*5b1fd00bSAndreas Gohr        /** @var helper_plugin_struct_db $struct */
19*5b1fd00bSAndreas Gohr        $struct = plugin_load('helper', 'struct_db');
20*5b1fd00bSAndreas Gohr        if(!$struct) {
21*5b1fd00bSAndreas Gohr            // FIXME show message?
22*5b1fd00bSAndreas Gohr            return null;
23ed00f27dSAndreas Gohr        }
24*5b1fd00bSAndreas Gohr        $sqlite = $struct->getDB(false);
25*5b1fd00bSAndreas Gohr        if(!$sqlite) return null;
26*5b1fd00bSAndreas Gohr
27*5b1fd00bSAndreas Gohr        // on init
28*5b1fd00bSAndreas Gohr        if(!$this->initialized) {
29*5b1fd00bSAndreas Gohr            $sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'isPublisher'], -1);
30*5b1fd00bSAndreas Gohr            $this->initialized = true;
31*5b1fd00bSAndreas Gohr        }
32*5b1fd00bSAndreas Gohr
33*5b1fd00bSAndreas Gohr        return $sqlite;
34ed00f27dSAndreas Gohr    }
35939e6e3cSAnna Dabrowska
36e394901aSAnna Dabrowska    /**
37910e7e15SAnna Dabrowska     * Get list of all pages known to the plugin
38910e7e15SAnna Dabrowska     * @return array
39910e7e15SAnna Dabrowska     */
40126b0b8eSAnna Dabrowska    public function getPages()
41910e7e15SAnna Dabrowska    {
42*5b1fd00bSAndreas Gohr        $sqlite = $this->getDB();
43*5b1fd00bSAndreas Gohr        if(!$sqlite) return [];
44*5b1fd00bSAndreas Gohr
45126b0b8eSAnna Dabrowska        $sql = 'SELECT pid FROM titles';
46*5b1fd00bSAndreas Gohr        $list = $sqlite->queryAll($sql);
47126b0b8eSAnna Dabrowska        return array_column($list, 'pid');
48910e7e15SAnna Dabrowska    }
49910e7e15SAnna Dabrowska
50910e7e15SAnna Dabrowska    /**
51939e6e3cSAnna Dabrowska     * Returns true if the current page is included in publishing workflows
52939e6e3cSAnna Dabrowska     *
53939e6e3cSAnna Dabrowska     * @return bool
54939e6e3cSAnna Dabrowska     */
55939e6e3cSAnna Dabrowska    public function isPublishable()
56939e6e3cSAnna Dabrowska    {
57939e6e3cSAnna Dabrowska        global $ID;
58*5b1fd00bSAndreas Gohr        $sqlite = $this->getDB();
59*5b1fd00bSAndreas Gohr        if(!$sqlite) return false;
60939e6e3cSAnna Dabrowska
61126b0b8eSAnna Dabrowska        $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1';
62*5b1fd00bSAndreas Gohr        return (bool) $sqlite->queryAll($sql, $ID);
63939e6e3cSAnna Dabrowska    }
642b546eccSAndreas Gohr
652b546eccSAndreas Gohr    /**
662b546eccSAndreas Gohr     * Check if the current user has the given roles on the current page
672b546eccSAndreas Gohr     *
682b546eccSAndreas Gohr     * @param string $pid The page ID to check access for
692b546eccSAndreas Gohr     * @param string[] $roles Roles needed. Empty for any role
702b546eccSAndreas Gohr     * @return bool
712b546eccSAndreas Gohr     */
722b546eccSAndreas Gohr    public function checkAccess($pid, $roles = [])
732b546eccSAndreas Gohr    {
74ed00f27dSAndreas Gohr        return self::userHasRole($pid, '', [], $roles);
75ed00f27dSAndreas Gohr    }
76ed00f27dSAndreas Gohr
77ed00f27dSAndreas Gohr    /**
78ed00f27dSAndreas Gohr     * Function registered in SQLite
79ed00f27dSAndreas Gohr     *
80ed00f27dSAndreas Gohr     * Params are read via function args
81ed00f27dSAndreas Gohr     *
82ed00f27dSAndreas Gohr     * @param ...string $pid, $userId, $groups...
83ed00f27dSAndreas Gohr     * @return int Return an integer instead of boolean for better sqlite compatibility
84ed00f27dSAndreas Gohr     */
85ed00f27dSAndreas Gohr    public function isPublisher()
86ed00f27dSAndreas Gohr    {
87ed00f27dSAndreas Gohr        if (!$this->isPublishable()) return 1;
88ed00f27dSAndreas Gohr
89ed00f27dSAndreas Gohr        global $USERINFO;
90ed00f27dSAndreas Gohr        global $INPUT;
91ed00f27dSAndreas Gohr
92ed00f27dSAndreas Gohr        $args = func_get_args();
93ed00f27dSAndreas Gohr        $pid = $args[0];
94ed00f27dSAndreas Gohr        $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER');
95ed00f27dSAndreas Gohr        $grps = $args[2] ?? ($USERINFO['grps'] ?? []);
96ed00f27dSAndreas Gohr
97ed00f27dSAndreas Gohr        return (int)$this->userHasRole(
98ed00f27dSAndreas Gohr            $pid,
99ed00f27dSAndreas Gohr            $userId,
100ed00f27dSAndreas Gohr            $grps
101ed00f27dSAndreas Gohr        );
102ed00f27dSAndreas Gohr    }
103ed00f27dSAndreas Gohr
104ed00f27dSAndreas Gohr    /**
105ed00f27dSAndreas Gohr     * Check if a given user has role assignment for a given page
106ed00f27dSAndreas Gohr     *
107ed00f27dSAndreas Gohr     * @param string $pid Page to check
108ed00f27dSAndreas Gohr     * @param string $userId User login name, current user if empty
109ed00f27dSAndreas Gohr     * @param string[] $grps Groups the user has, current user's groups if empty user
110ed00f27dSAndreas Gohr     * @param string[] $roles Roles the user should have, empty for any role
111ed00f27dSAndreas Gohr     * @return bool
112ed00f27dSAndreas Gohr     */
113ed00f27dSAndreas Gohr    public static function userHasRole($pid, $userId = '', $grps = [], $roles = [])
114ed00f27dSAndreas Gohr    {
115ed00f27dSAndreas Gohr        global $INPUT;
116ed00f27dSAndreas Gohr        global $USERINFO;
117ed00f27dSAndreas Gohr
118ed00f27dSAndreas Gohr        if (blank($userId)) {
119ed00f27dSAndreas Gohr            $userId = $INPUT->server->str('REMOTE_USER');
120ed00f27dSAndreas Gohr            $grps = $USERINFO['grps'] ?? [];
121ed00f27dSAndreas Gohr        }
122ed00f27dSAndreas Gohr
123ed00f27dSAndreas Gohr        $assignments = Assignments::getInstance();
124ed00f27dSAndreas Gohr        $rules = $assignments->getPageAssignments($pid);
125ed00f27dSAndreas Gohr
126ed00f27dSAndreas Gohr        // if no roles are given, any role is fine
127ed00f27dSAndreas Gohr        if (empty($roles)) {
128ed00f27dSAndreas Gohr            return auth_isMember(
129ed00f27dSAndreas Gohr                implode(',', array_merge(...array_values($rules))),
130ed00f27dSAndreas Gohr                $userId,
131ed00f27dSAndreas Gohr                $grps
132ed00f27dSAndreas Gohr            );
133ed00f27dSAndreas Gohr        }
134ed00f27dSAndreas Gohr
135ed00f27dSAndreas Gohr        foreach ($roles as $role) {
136ed00f27dSAndreas Gohr            if (isset($rules[$role])) {
137ed00f27dSAndreas Gohr                $users = $rules[$role];
138ed00f27dSAndreas Gohr                if (auth_isMember(implode(',', $users), $userId, $grps)) {
139ed00f27dSAndreas Gohr                    return true;
140ed00f27dSAndreas Gohr                }
141ed00f27dSAndreas Gohr            }
142ed00f27dSAndreas Gohr        }
143ed00f27dSAndreas Gohr
144ed00f27dSAndreas Gohr        return false;
1452b546eccSAndreas Gohr    }
1462b546eccSAndreas Gohr
147e394901aSAnna Dabrowska}
148