1e394901aSAnna Dabrowska<?php 2e394901aSAnna Dabrowska 3*9ab8cbaeSanndause dokuwiki\Extension\Plugin; 4*9ab8cbaeSanndause dokuwiki\plugin\sqlite\SQLiteDB; 5ed00f27dSAndreas Gohruse dokuwiki\plugin\structpublish\meta\Assignments; 6ed00f27dSAndreas Gohr 7*9ab8cbaeSanndaclass helper_plugin_structpublish_db extends Plugin 85b1fd00bSAndreas Gohr{ 95b1fd00bSAndreas Gohr protected $initialized = false; 105b1fd00bSAndreas Gohr 11ed00f27dSAndreas Gohr /** 125b1fd00bSAndreas Gohr * Access the struct database 135b1fd00bSAndreas Gohr * 145b1fd00bSAndreas Gohr * Registers our own IS_PUBLISHER function with sqlite 155b1fd00bSAndreas Gohr * 16*9ab8cbaeSannda * @return SQLiteDB|null 17ed00f27dSAndreas Gohr */ 185b1fd00bSAndreas Gohr public function getDB() 19e394901aSAnna Dabrowska { 205b1fd00bSAndreas Gohr /** @var helper_plugin_struct_db $struct */ 215b1fd00bSAndreas Gohr $struct = plugin_load('helper', 'struct_db'); 225b1fd00bSAndreas Gohr if (!$struct) { 235b1fd00bSAndreas Gohr // FIXME show message? 245b1fd00bSAndreas Gohr return null; 25ed00f27dSAndreas Gohr } 265b1fd00bSAndreas Gohr $sqlite = $struct->getDB(false); 2731e730e1SAnna Dabrowska if (!$sqlite) { 2831e730e1SAnna Dabrowska return null; 2931e730e1SAnna Dabrowska } 305b1fd00bSAndreas Gohr 315b1fd00bSAndreas Gohr // on init 325b1fd00bSAndreas Gohr if (!$this->initialized) { 335b1fd00bSAndreas Gohr $sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'isPublisher'], -1); 345b1fd00bSAndreas Gohr $this->initialized = true; 355b1fd00bSAndreas Gohr } 365b1fd00bSAndreas Gohr 375b1fd00bSAndreas Gohr return $sqlite; 38ed00f27dSAndreas Gohr } 39939e6e3cSAnna Dabrowska 40e394901aSAnna Dabrowska /** 41910e7e15SAnna Dabrowska * Get list of all pages known to the plugin 4231e730e1SAnna Dabrowska * 43910e7e15SAnna Dabrowska * @return array 44910e7e15SAnna Dabrowska */ 45126b0b8eSAnna Dabrowska public function getPages() 46910e7e15SAnna Dabrowska { 475b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 4831e730e1SAnna Dabrowska if (!$sqlite) { 4931e730e1SAnna Dabrowska return []; 5031e730e1SAnna Dabrowska } 515b1fd00bSAndreas Gohr 52126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM titles'; 535b1fd00bSAndreas Gohr $list = $sqlite->queryAll($sql); 54126b0b8eSAnna Dabrowska return array_column($list, 'pid'); 55910e7e15SAnna Dabrowska } 56910e7e15SAnna Dabrowska 57910e7e15SAnna Dabrowska /** 582467315aSAnna Dabrowska * Returns true if the given page is included in publishing workflows. 592467315aSAnna Dabrowska * If no pid is given, check current page. 60939e6e3cSAnna Dabrowska * 61939e6e3cSAnna Dabrowska * @return bool 62939e6e3cSAnna Dabrowska */ 632467315aSAnna Dabrowska public function isPublishable($pid = null) 64939e6e3cSAnna Dabrowska { 65939e6e3cSAnna Dabrowska global $ID; 665b1fd00bSAndreas Gohr $sqlite = $this->getDB(); 6731e730e1SAnna Dabrowska if (!$sqlite) { 6831e730e1SAnna Dabrowska return false; 6931e730e1SAnna Dabrowska } 70939e6e3cSAnna Dabrowska 7131e730e1SAnna Dabrowska if (!$pid) { 7231e730e1SAnna Dabrowska $pid = $ID; 7331e730e1SAnna Dabrowska } 742467315aSAnna Dabrowska 75126b0b8eSAnna Dabrowska $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; 762467315aSAnna Dabrowska return (bool) $sqlite->queryAll($sql, $pid); 77939e6e3cSAnna Dabrowska } 782b546eccSAndreas Gohr 792b546eccSAndreas Gohr /** 802b546eccSAndreas Gohr * Check if the current user has the given roles on the current page 812b546eccSAndreas Gohr * 822b546eccSAndreas Gohr * @param string $pid The page ID to check access for 832b546eccSAndreas Gohr * @param string[] $roles Roles needed. Empty for any role 842b546eccSAndreas Gohr * @return bool 852b546eccSAndreas Gohr */ 862b546eccSAndreas Gohr public function checkAccess($pid, $roles = []) 872b546eccSAndreas Gohr { 88ed00f27dSAndreas Gohr return self::userHasRole($pid, '', [], $roles); 89ed00f27dSAndreas Gohr } 90ed00f27dSAndreas Gohr 91ed00f27dSAndreas Gohr /** 92ed00f27dSAndreas Gohr * Function registered in SQLite 93ed00f27dSAndreas Gohr * 94ed00f27dSAndreas Gohr * Params are read via function args 95ed00f27dSAndreas Gohr * 96ed00f27dSAndreas Gohr * @param ...string $pid, $userId, $groups... 97ed00f27dSAndreas Gohr * @return int Return an integer instead of boolean for better sqlite compatibility 98ed00f27dSAndreas Gohr */ 99*9ab8cbaeSannda public function isPublisher(...$args) 100ed00f27dSAndreas Gohr { 101ed00f27dSAndreas Gohr 102ed00f27dSAndreas Gohr global $USERINFO; 103ed00f27dSAndreas Gohr global $INPUT; 104ed00f27dSAndreas Gohr $pid = $args[0]; 1052467315aSAnna Dabrowska 10631e730e1SAnna 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 113*9ab8cbaeSannda return (int)static::userHasRole($pid, $userId, $grps); 114ed00f27dSAndreas Gohr } 115ed00f27dSAndreas Gohr 116ed00f27dSAndreas Gohr /** 117ed00f27dSAndreas Gohr * Check if a given user has role assignment for a given page 118ed00f27dSAndreas Gohr * 119ed00f27dSAndreas Gohr * @param string $pid Page to check 120ed00f27dSAndreas Gohr * @param string $userId User login name, current user if empty 121ed00f27dSAndreas Gohr * @param string[] $grps Groups the user has, current user's groups if empty user 122ed00f27dSAndreas Gohr * @param string[] $roles Roles the user should have, empty for any role 123ed00f27dSAndreas Gohr * @return bool 124ed00f27dSAndreas Gohr */ 125ed00f27dSAndreas Gohr public static function userHasRole($pid, $userId = '', $grps = [], $roles = []) 126ed00f27dSAndreas Gohr { 127ed00f27dSAndreas Gohr global $INPUT; 128ed00f27dSAndreas Gohr global $USERINFO; 129ed00f27dSAndreas Gohr 130ed00f27dSAndreas Gohr if (blank($userId)) { 131ed00f27dSAndreas Gohr $userId = $INPUT->server->str('REMOTE_USER'); 132ed00f27dSAndreas Gohr $grps = $USERINFO['grps'] ?? []; 133ed00f27dSAndreas Gohr } 134ed00f27dSAndreas Gohr 135ed00f27dSAndreas Gohr $assignments = Assignments::getInstance(); 136ed00f27dSAndreas Gohr $rules = $assignments->getPageAssignments($pid); 137ed00f27dSAndreas Gohr 138ed00f27dSAndreas Gohr // if no roles are given, any role is fine 139ed00f27dSAndreas Gohr if (empty($roles)) { 140ed00f27dSAndreas Gohr return auth_isMember( 141ed00f27dSAndreas Gohr implode(',', array_merge(...array_values($rules))), 142ed00f27dSAndreas Gohr $userId, 143ed00f27dSAndreas Gohr $grps 144ed00f27dSAndreas Gohr ); 145ed00f27dSAndreas Gohr } 146ed00f27dSAndreas Gohr 147ed00f27dSAndreas Gohr foreach ($roles as $role) { 148ed00f27dSAndreas Gohr if (isset($rules[$role])) { 149ed00f27dSAndreas Gohr $users = $rules[$role]; 150ed00f27dSAndreas Gohr if (auth_isMember(implode(',', $users), $userId, $grps)) { 151ed00f27dSAndreas Gohr return true; 152ed00f27dSAndreas Gohr } 153ed00f27dSAndreas Gohr } 154ed00f27dSAndreas Gohr } 155ed00f27dSAndreas Gohr 156ed00f27dSAndreas Gohr return false; 1572b546eccSAndreas Gohr } 158e394901aSAnna Dabrowska} 159