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