1<?php 2 3use dokuwiki\plugin\structpublish\meta\Assignments; 4 5/** 6 * @todo by extending helper_plugin_struct_db we break the singlton pattern and have two database connections 7 */ 8class helper_plugin_structpublish_db extends helper_plugin_struct_db 9{ 10 /** @inheritdoc */ 11 protected function init() 12 { 13 parent::init(); 14 if ($this->sqlite) { 15 $this->sqlite->create_function('IS_PUBLISHER', [$this, 'isPublisher'], -1); 16 } 17 } 18 19 /** 20 * Get list of all pages known to the plugin 21 * @return array 22 */ 23 public function getPages() 24 { 25 $sql = 'SELECT pid FROM titles'; 26 $res = $this->sqlite->query($sql); 27 $list = $this->sqlite->res2arr($res); 28 $this->sqlite->res_close($res); 29 return array_column($list, 'pid'); 30 } 31 32 /** 33 * Returns true if the current page is included in publishing workflows 34 * 35 * @return bool 36 */ 37 public function isPublishable() 38 { 39 global $ID; 40 41 $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; 42 $res = $this->sqlite->query($sql, $ID); 43 if ($res && $this->sqlite->res2count($res)) { 44 return true; 45 } 46 return false; 47 } 48 49 /** 50 * Check if the current user has the given roles on the current page 51 * 52 * @param string $pid The page ID to check access for 53 * @param string[] $roles Roles needed. Empty for any role 54 * @return bool 55 */ 56 public function checkAccess($pid, $roles = []) 57 { 58 return self::userHasRole($pid, '', [], $roles); 59 } 60 61 /** 62 * Function registered in SQLite 63 * 64 * Params are read via function args 65 * 66 * @param ...string $pid, $userId, $groups... 67 * @return int Return an integer instead of boolean for better sqlite compatibility 68 */ 69 public function isPublisher() 70 { 71 if (!$this->isPublishable()) return 1; 72 73 global $USERINFO; 74 global $INPUT; 75 76 $args = func_get_args(); 77 $pid = $args[0]; 78 $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER'); 79 $grps = $args[2] ?? ($USERINFO['grps'] ?? []); 80 81 return (int)$this->userHasRole( 82 $pid, 83 $userId, 84 $grps 85 ); 86 } 87 88 /** 89 * Check if a given user has role assignment for a given page 90 * 91 * @param string $pid Page to check 92 * @param string $userId User login name, current user if empty 93 * @param string[] $grps Groups the user has, current user's groups if empty user 94 * @param string[] $roles Roles the user should have, empty for any role 95 * @return bool 96 */ 97 public static function userHasRole($pid, $userId = '', $grps = [], $roles = []) 98 { 99 global $INPUT; 100 global $USERINFO; 101 102 if (blank($userId)) { 103 $userId = $INPUT->server->str('REMOTE_USER'); 104 $grps = $USERINFO['grps'] ?? []; 105 } 106 107 $assignments = Assignments::getInstance(); 108 $rules = $assignments->getPageAssignments($pid); 109 110 // if no roles are given, any role is fine 111 if (empty($roles)) { 112 return auth_isMember( 113 implode(',', array_merge(...array_values($rules))), 114 $userId, 115 $grps 116 ); 117 } 118 119 foreach ($roles as $role) { 120 if (isset($rules[$role])) { 121 $users = $rules[$role]; 122 if (auth_isMember(implode(',', $users), $userId, $grps)) { 123 return true; 124 } 125 } 126 } 127 128 return false; 129 } 130 131} 132