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->getPdo()->sqliteCreateFunction('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 $list = $this->sqlite->queryAll($sql); 27 return array_column($list, 'pid'); 28 } 29 30 /** 31 * Returns true if the current page is included in publishing workflows 32 * 33 * @return bool 34 */ 35 public function isPublishable() 36 { 37 global $ID; 38 39 $sql = 'SELECT pid FROM structpublish_assignments WHERE pid = ? AND assigned = 1'; 40 return (bool) $this->sqlite->queryAll($sql, $ID); 41 } 42 43 /** 44 * Check if the current user has the given roles on the current page 45 * 46 * @param string $pid The page ID to check access for 47 * @param string[] $roles Roles needed. Empty for any role 48 * @return bool 49 */ 50 public function checkAccess($pid, $roles = []) 51 { 52 return self::userHasRole($pid, '', [], $roles); 53 } 54 55 /** 56 * Function registered in SQLite 57 * 58 * Params are read via function args 59 * 60 * @param ...string $pid, $userId, $groups... 61 * @return int Return an integer instead of boolean for better sqlite compatibility 62 */ 63 public function isPublisher() 64 { 65 if (!$this->isPublishable()) return 1; 66 67 global $USERINFO; 68 global $INPUT; 69 70 $args = func_get_args(); 71 $pid = $args[0]; 72 $userId = $args[1] ?? $INPUT->server->str('REMOTE_USER'); 73 $grps = $args[2] ?? ($USERINFO['grps'] ?? []); 74 75 return (int)$this->userHasRole( 76 $pid, 77 $userId, 78 $grps 79 ); 80 } 81 82 /** 83 * Check if a given user has role assignment for a given page 84 * 85 * @param string $pid Page to check 86 * @param string $userId User login name, current user if empty 87 * @param string[] $grps Groups the user has, current user's groups if empty user 88 * @param string[] $roles Roles the user should have, empty for any role 89 * @return bool 90 */ 91 public static function userHasRole($pid, $userId = '', $grps = [], $roles = []) 92 { 93 global $INPUT; 94 global $USERINFO; 95 96 if (blank($userId)) { 97 $userId = $INPUT->server->str('REMOTE_USER'); 98 $grps = $USERINFO['grps'] ?? []; 99 } 100 101 $assignments = Assignments::getInstance(); 102 $rules = $assignments->getPageAssignments($pid); 103 104 // if no roles are given, any role is fine 105 if (empty($roles)) { 106 return auth_isMember( 107 implode(',', array_merge(...array_values($rules))), 108 $userId, 109 $grps 110 ); 111 } 112 113 foreach ($roles as $role) { 114 if (isset($rules[$role])) { 115 $users = $rules[$role]; 116 if (auth_isMember(implode(',', $users), $userId, $grps)) { 117 return true; 118 } 119 } 120 } 121 122 return false; 123 } 124 125} 126