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