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); 25*31e730e1SAnna Dabrowska if (!$sqlite) { 26*31e730e1SAnna Dabrowska return null; 27*31e730e1SAnna Dabrowska } 285b1fd00bSAndreas Gohr 295b1fd00bSAndreas Gohr // on init 305b1fd00bSAndreas Gohr if (!$this->initialized) { 315b1fd00bSAndreas Gohr $sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'isPublisher'], -1); 325b1fd00bSAndreas Gohr $this->initialized = true; 335b1fd00bSAndreas Gohr } 345b1fd00bSAndreas Gohr 355b1fd00bSAndreas Gohr return $sqlite; 36ed00f27dSAndreas Gohr } 37939e6e3cSAnna Dabrowska 38e394901aSAnna Dabrowska /** 39910e7e15SAnna Dabrowska * Get list of all pages known to the plugin 40*31e730e1SAnna Dabrowska * 41910e7e15SAnna Dabrowska * @return array 42910e7e15SAnna Dabrowska */ 43126b0b8eSAnna Dabrowska public function getPages() 44910e7e15SAnna Dabrowska { 455b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 46*31e730e1SAnna Dabrowska if (!$sqlite) { 47*31e730e1SAnna Dabrowska return []; 48*31e730e1SAnna Dabrowska } 495b1fd00bSAndreas Gohr 50126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM titles'; 515b1fd00bSAndreas Gohr $list = $sqlite->queryAll($sql); 52126b0b8eSAnna Dabrowska return array_column($list, 'pid'); 53910e7e15SAnna Dabrowska } 54910e7e15SAnna Dabrowska 55910e7e15SAnna Dabrowska /** 562467315aSAnna Dabrowska * Returns true if the given page is included in publishing workflows. 572467315aSAnna Dabrowska * If no pid is given, check current page. 58939e6e3cSAnna Dabrowska * 59939e6e3cSAnna Dabrowska * @return bool 60939e6e3cSAnna Dabrowska */ 612467315aSAnna Dabrowska public function isPublishable($pid = null) 62939e6e3cSAnna Dabrowska { 63939e6e3cSAnna Dabrowska global $ID; 645b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 65*31e730e1SAnna Dabrowska if (!$sqlite) { 66*31e730e1SAnna Dabrowska return false; 67*31e730e1SAnna Dabrowska } 68939e6e3cSAnna Dabrowska 69*31e730e1SAnna Dabrowska if (!$pid) { 70*31e730e1SAnna Dabrowska $pid = $ID; 71*31e730e1SAnna Dabrowska } 722467315aSAnna Dabrowska 73126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; 742467315aSAnna Dabrowska return (bool) $sqlite->queryAll($sql, $pid); 75939e6e3cSAnna Dabrowska } 762b546eccSAndreas Gohr 772b546eccSAndreas Gohr /** 782b546eccSAndreas Gohr * Check if the current user has the given roles on the current page 792b546eccSAndreas Gohr * 802b546eccSAndreas Gohr * @param string $pid The page ID to check access for 812b546eccSAndreas Gohr * @param string[] $roles Roles needed. Empty for any role 822b546eccSAndreas Gohr * @return bool 832b546eccSAndreas Gohr */ 842b546eccSAndreas Gohr public function checkAccess($pid, $roles = []) 852b546eccSAndreas Gohr { 86ed00f27dSAndreas Gohr return self::userHasRole($pid, '', [], $roles); 87ed00f27dSAndreas Gohr } 88ed00f27dSAndreas Gohr 89ed00f27dSAndreas Gohr /** 90ed00f27dSAndreas Gohr * Function registered in SQLite 91ed00f27dSAndreas Gohr * 92ed00f27dSAndreas Gohr * Params are read via function args 93ed00f27dSAndreas Gohr * 94ed00f27dSAndreas Gohr * @param ...string $pid, $userId, $groups... 95ed00f27dSAndreas Gohr * @return int Return an integer instead of boolean for better sqlite compatibility 96ed00f27dSAndreas Gohr */ 97ed00f27dSAndreas Gohr public function isPublisher() 98ed00f27dSAndreas Gohr { 99ed00f27dSAndreas Gohr 100ed00f27dSAndreas Gohr global $USERINFO; 101ed00f27dSAndreas Gohr global $INPUT; 102ed00f27dSAndreas Gohr 103ed00f27dSAndreas Gohr $args = func_get_args(); 104ed00f27dSAndreas Gohr $pid = $args[0]; 1052467315aSAnna Dabrowska 106*31e730e1SAnna Dabrowska if (!$pid || !$this->isPublishable($pid)) { 1072467315aSAnna Dabrowska return 1; 1082467315aSAnna Dabrowska } 1092467315aSAnna Dabrowska 110ed00f27dSAndreas Gohr $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER'); 111ed00f27dSAndreas Gohr $grps = $args[2] ?? ($USERINFO['grps'] ?? []); 112ed00f27dSAndreas Gohr 113ed00f27dSAndreas Gohr return (int)$this->userHasRole( 114ed00f27dSAndreas Gohr $pid, 115ed00f27dSAndreas Gohr $userId, 116ed00f27dSAndreas Gohr $grps 117ed00f27dSAndreas Gohr ); 118ed00f27dSAndreas Gohr } 119ed00f27dSAndreas Gohr 120ed00f27dSAndreas Gohr /** 121ed00f27dSAndreas Gohr * Check if a given user has role assignment for a given page 122ed00f27dSAndreas Gohr * 123ed00f27dSAndreas Gohr * @param string $pid Page to check 124ed00f27dSAndreas Gohr * @param string $userId User login name, current user if empty 125ed00f27dSAndreas Gohr * @param string[] $grps Groups the user has, current user's groups if empty user 126ed00f27dSAndreas Gohr * @param string[] $roles Roles the user should have, empty for any role 127ed00f27dSAndreas Gohr * @return bool 128ed00f27dSAndreas Gohr */ 129ed00f27dSAndreas Gohr public static function userHasRole($pid, $userId = '', $grps = [], $roles = []) 130ed00f27dSAndreas Gohr { 131ed00f27dSAndreas Gohr global $INPUT; 132ed00f27dSAndreas Gohr global $USERINFO; 133ed00f27dSAndreas Gohr 134ed00f27dSAndreas Gohr if (blank($userId)) { 135ed00f27dSAndreas Gohr $userId = $INPUT->server->str('REMOTE_USER'); 136ed00f27dSAndreas Gohr $grps = $USERINFO['grps'] ?? []; 137ed00f27dSAndreas Gohr } 138ed00f27dSAndreas Gohr 139ed00f27dSAndreas Gohr $assignments = Assignments::getInstance(); 140ed00f27dSAndreas Gohr $rules = $assignments->getPageAssignments($pid); 141ed00f27dSAndreas Gohr 142ed00f27dSAndreas Gohr // if no roles are given, any role is fine 143ed00f27dSAndreas Gohr if (empty($roles)) { 144ed00f27dSAndreas Gohr return auth_isMember( 145ed00f27dSAndreas Gohr implode(',', array_merge(...array_values($rules))), 146ed00f27dSAndreas Gohr $userId, 147ed00f27dSAndreas Gohr $grps 148ed00f27dSAndreas Gohr ); 149ed00f27dSAndreas Gohr } 150ed00f27dSAndreas Gohr 151ed00f27dSAndreas Gohr foreach ($roles as $role) { 152ed00f27dSAndreas Gohr if (isset($rules[$role])) { 153ed00f27dSAndreas Gohr $users = $rules[$role]; 154ed00f27dSAndreas Gohr if (auth_isMember(implode(',', $users), $userId, $grps)) { 155ed00f27dSAndreas Gohr return true; 156ed00f27dSAndreas Gohr } 157ed00f27dSAndreas Gohr } 158ed00f27dSAndreas Gohr } 159ed00f27dSAndreas Gohr 160ed00f27dSAndreas Gohr return false; 1612b546eccSAndreas Gohr } 162e394901aSAnna Dabrowska} 163