1e394901aSAnna Dabrowska<?php 2e394901aSAnna Dabrowska 3ed00f27dSAndreas Gohruse dokuwiki\plugin\structpublish\meta\Assignments; 4ed00f27dSAndreas Gohr 55b1fd00bSAndreas Gohrclass helper_plugin_structpublish_db extends DokuWiki_Plugin 65b1fd00bSAndreas Gohr{ 75b1fd00bSAndreas Gohr protected $initialized = false; 85b1fd00bSAndreas Gohr 9ed00f27dSAndreas Gohr /** 105b1fd00bSAndreas Gohr * Access the struct database 115b1fd00bSAndreas Gohr * 125b1fd00bSAndreas Gohr * Registers our own IS_PUBLISHER function with sqlite 135b1fd00bSAndreas Gohr * 145b1fd00bSAndreas Gohr * @return \dokuwiki\plugin\sqlite\SQLiteDB|null 15ed00f27dSAndreas Gohr */ 165b1fd00bSAndreas Gohr public function getDB() 17e394901aSAnna Dabrowska { 185b1fd00bSAndreas Gohr /** @var helper_plugin_struct_db $struct */ 195b1fd00bSAndreas Gohr $struct = plugin_load('helper', 'struct_db'); 205b1fd00bSAndreas Gohr if(!$struct) { 215b1fd00bSAndreas Gohr // FIXME show message? 225b1fd00bSAndreas Gohr return null; 23ed00f27dSAndreas Gohr } 245b1fd00bSAndreas Gohr $sqlite = $struct->getDB(false); 255b1fd00bSAndreas Gohr if(!$sqlite) return null; 265b1fd00bSAndreas Gohr 275b1fd00bSAndreas Gohr // on init 285b1fd00bSAndreas Gohr if(!$this->initialized) { 295b1fd00bSAndreas Gohr $sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'isPublisher'], -1); 305b1fd00bSAndreas Gohr $this->initialized = true; 315b1fd00bSAndreas Gohr } 325b1fd00bSAndreas Gohr 335b1fd00bSAndreas 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 { 425b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 435b1fd00bSAndreas Gohr if(!$sqlite) return []; 445b1fd00bSAndreas Gohr 45126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM titles'; 465b1fd00bSAndreas Gohr $list = $sqlite->queryAll($sql); 47126b0b8eSAnna Dabrowska return array_column($list, 'pid'); 48910e7e15SAnna Dabrowska } 49910e7e15SAnna Dabrowska 50910e7e15SAnna Dabrowska /** 51*2467315aSAnna Dabrowska * Returns true if the given page is included in publishing workflows. 52*2467315aSAnna Dabrowska * If no pid is given, check current page. 53939e6e3cSAnna Dabrowska * 54939e6e3cSAnna Dabrowska * @return bool 55939e6e3cSAnna Dabrowska */ 56*2467315aSAnna Dabrowska public function isPublishable($pid = null) 57939e6e3cSAnna Dabrowska { 58939e6e3cSAnna Dabrowska global $ID; 595b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 605b1fd00bSAndreas Gohr if(!$sqlite) return false; 61939e6e3cSAnna Dabrowska 62*2467315aSAnna Dabrowska if (!$pid) $pid = $ID; 63*2467315aSAnna Dabrowska 64126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; 65*2467315aSAnna Dabrowska return (bool) $sqlite->queryAll($sql, $pid); 66939e6e3cSAnna Dabrowska } 672b546eccSAndreas Gohr 682b546eccSAndreas Gohr /** 692b546eccSAndreas Gohr * Check if the current user has the given roles on the current page 702b546eccSAndreas Gohr * 712b546eccSAndreas Gohr * @param string $pid The page ID to check access for 722b546eccSAndreas Gohr * @param string[] $roles Roles needed. Empty for any role 732b546eccSAndreas Gohr * @return bool 742b546eccSAndreas Gohr */ 752b546eccSAndreas Gohr public function checkAccess($pid, $roles = []) 762b546eccSAndreas Gohr { 77ed00f27dSAndreas Gohr return self::userHasRole($pid, '', [], $roles); 78ed00f27dSAndreas Gohr } 79ed00f27dSAndreas Gohr 80ed00f27dSAndreas Gohr /** 81ed00f27dSAndreas Gohr * Function registered in SQLite 82ed00f27dSAndreas Gohr * 83ed00f27dSAndreas Gohr * Params are read via function args 84ed00f27dSAndreas Gohr * 85ed00f27dSAndreas Gohr * @param ...string $pid, $userId, $groups... 86ed00f27dSAndreas Gohr * @return int Return an integer instead of boolean for better sqlite compatibility 87ed00f27dSAndreas Gohr */ 88ed00f27dSAndreas Gohr public function isPublisher() 89ed00f27dSAndreas Gohr { 90ed00f27dSAndreas Gohr 91ed00f27dSAndreas Gohr global $USERINFO; 92ed00f27dSAndreas Gohr global $INPUT; 93ed00f27dSAndreas Gohr 94ed00f27dSAndreas Gohr $args = func_get_args(); 95ed00f27dSAndreas Gohr $pid = $args[0]; 96*2467315aSAnna Dabrowska 97*2467315aSAnna Dabrowska if (!$pid) return 1; 98*2467315aSAnna Dabrowska 99*2467315aSAnna Dabrowska if (!$this->isPublishable($pid)) { 100*2467315aSAnna Dabrowska return 1; 101*2467315aSAnna Dabrowska } 102*2467315aSAnna Dabrowska 103ed00f27dSAndreas Gohr $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER'); 104ed00f27dSAndreas Gohr $grps = $args[2] ?? ($USERINFO['grps'] ?? []); 105ed00f27dSAndreas Gohr 106ed00f27dSAndreas Gohr return (int)$this->userHasRole( 107ed00f27dSAndreas Gohr $pid, 108ed00f27dSAndreas Gohr $userId, 109ed00f27dSAndreas Gohr $grps 110ed00f27dSAndreas Gohr ); 111ed00f27dSAndreas Gohr } 112ed00f27dSAndreas Gohr 113ed00f27dSAndreas Gohr /** 114ed00f27dSAndreas Gohr * Check if a given user has role assignment for a given page 115ed00f27dSAndreas Gohr * 116ed00f27dSAndreas Gohr * @param string $pid Page to check 117ed00f27dSAndreas Gohr * @param string $userId User login name, current user if empty 118ed00f27dSAndreas Gohr * @param string[] $grps Groups the user has, current user's groups if empty user 119ed00f27dSAndreas Gohr * @param string[] $roles Roles the user should have, empty for any role 120ed00f27dSAndreas Gohr * @return bool 121ed00f27dSAndreas Gohr */ 122ed00f27dSAndreas Gohr public static function userHasRole($pid, $userId = '', $grps = [], $roles = []) 123ed00f27dSAndreas Gohr { 124ed00f27dSAndreas Gohr global $INPUT; 125ed00f27dSAndreas Gohr global $USERINFO; 126ed00f27dSAndreas Gohr 127ed00f27dSAndreas Gohr if (blank($userId)) { 128ed00f27dSAndreas Gohr $userId = $INPUT->server->str('REMOTE_USER'); 129ed00f27dSAndreas Gohr $grps = $USERINFO['grps'] ?? []; 130ed00f27dSAndreas Gohr } 131ed00f27dSAndreas Gohr 132ed00f27dSAndreas Gohr $assignments = Assignments::getInstance(); 133ed00f27dSAndreas Gohr $rules = $assignments->getPageAssignments($pid); 134ed00f27dSAndreas Gohr 135ed00f27dSAndreas Gohr // if no roles are given, any role is fine 136ed00f27dSAndreas Gohr if (empty($roles)) { 137ed00f27dSAndreas Gohr return auth_isMember( 138ed00f27dSAndreas Gohr implode(',', array_merge(...array_values($rules))), 139ed00f27dSAndreas Gohr $userId, 140ed00f27dSAndreas Gohr $grps 141ed00f27dSAndreas Gohr ); 142ed00f27dSAndreas Gohr } 143ed00f27dSAndreas Gohr 144ed00f27dSAndreas Gohr foreach ($roles as $role) { 145ed00f27dSAndreas Gohr if (isset($rules[$role])) { 146ed00f27dSAndreas Gohr $users = $rules[$role]; 147ed00f27dSAndreas Gohr if (auth_isMember(implode(',', $users), $userId, $grps)) { 148ed00f27dSAndreas Gohr return true; 149ed00f27dSAndreas Gohr } 150ed00f27dSAndreas Gohr } 151ed00f27dSAndreas Gohr } 152ed00f27dSAndreas Gohr 153ed00f27dSAndreas Gohr return false; 1542b546eccSAndreas Gohr } 1552b546eccSAndreas Gohr 156e394901aSAnna Dabrowska} 157