See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Contains the class used for the displaying the tokens table. 19 * 20 * @package core_webservice 21 * @copyright 2017 John Okely <john@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_webservice; 26 27 defined('MOODLE_INTERNAL') || die; 28 29 require_once($CFG->libdir . '/tablelib.php'); 30 require_once($CFG->dirroot . '/webservice/lib.php'); 31 require_once($CFG->dirroot . '/user/lib.php'); 32 33 /** 34 * Class for the displaying the participants table. 35 * 36 * @package core_webservice 37 * @copyright 2017 John Okely <john@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class token_table extends \table_sql { 41 42 /** 43 * @var bool $showalltokens Whether or not the user is able to see all tokens. 44 */ 45 protected $showalltokens; 46 47 /** @var bool $hasviewfullnames Does the user have the viewfullnames capability. */ 48 protected $hasviewfullnames; 49 50 /** @var array */ 51 protected $userextrafields; 52 53 /** @var object */ 54 protected $filterdata; 55 56 /** 57 * Sets up the table. 58 * 59 * @param int $id The id of the table 60 * @param object $filterdata The data submitted by the {@see token_filter}. 61 */ 62 public function __construct($id, $filterdata = null) { 63 parent::__construct($id); 64 65 // Get the context. 66 $context = \context_system::instance(); 67 68 // Can we see tokens created by all users? 69 $this->showalltokens = has_capability('moodle/webservice:managealltokens', $context); 70 $this->hasviewfullnames = has_capability('moodle/site:viewfullnames', $context); 71 72 // List of user identity fields. 73 $this->userextrafields = \core_user\fields::get_identity_fields(\context_system::instance(), false); 74 75 // Filter form values. 76 $this->filterdata = $filterdata; 77 78 // Define the headers and columns. 79 $headers = []; 80 $columns = []; 81 82 $headers[] = get_string('token', 'webservice'); 83 $columns[] = 'token'; 84 $headers[] = get_string('user'); 85 $columns[] = 'fullname'; 86 $headers[] = get_string('service', 'webservice'); 87 $columns[] = 'servicename'; 88 $headers[] = get_string('iprestriction', 'webservice'); 89 $columns[] = 'iprestriction'; 90 $headers[] = get_string('validuntil', 'webservice'); 91 $columns[] = 'validuntil'; 92 if ($this->showalltokens) { 93 // Only need to show creator if you can see tokens created by other people. 94 $headers[] = get_string('tokencreator', 'webservice'); 95 $columns[] = 'creatorlastname'; // So we can have semi-useful sorting. Table SQL doesn't two fullname collumns. 96 } 97 $headers[] = get_string('operation', 'webservice'); 98 $columns[] = 'operation'; 99 100 $this->define_columns($columns); 101 $this->define_headers($headers); 102 103 $this->no_sorting('operation'); 104 $this->no_sorting('token'); 105 $this->no_sorting('iprestriction'); 106 107 $this->set_attribute('id', $id); 108 } 109 110 /** 111 * Generate the operation column. 112 * 113 * @param \stdClass $data Data for the current row 114 * @return string Content for the column 115 */ 116 public function col_operation($data) { 117 $tokenpageurl = new \moodle_url( 118 "/admin/webservice/tokens.php", 119 [ 120 "action" => "delete", 121 "tokenid" => $data->id 122 ] 123 ); 124 return \html_writer::link($tokenpageurl, get_string("delete")); 125 } 126 127 /** 128 * Generate the validuntil column. 129 * 130 * @param \stdClass $data Data for the current row 131 * @return string Content for the column 132 */ 133 public function col_validuntil($data) { 134 if (empty($data->validuntil)) { 135 return ''; 136 } else { 137 return userdate($data->validuntil, get_string('strftimedatetime', 'langconfig')); 138 } 139 } 140 141 /** 142 * Generate the fullname column. Also includes capabilities the user is missing for the webservice (if any) 143 * 144 * @param \stdClass $data Data for the current row 145 * @return string Content for the column 146 */ 147 public function col_fullname($data) { 148 global $OUTPUT; 149 150 $identity = []; 151 152 foreach ($this->userextrafields as $userextrafield) { 153 $identity[] = s($data->$userextrafield); 154 } 155 156 $userprofilurl = new \moodle_url('/user/profile.php', ['id' => $data->userid]); 157 $content = \html_writer::link($userprofilurl, fullname($data, $this->hasviewfullnames)); 158 159 if ($identity) { 160 $content .= \html_writer::div('<small>' . implode(', ', $identity) . '</small>', 'useridentity text-muted'); 161 } 162 163 // Make up list of capabilities that the user is missing for the given webservice. 164 $webservicemanager = new \webservice(); 165 $usermissingcaps = $webservicemanager->get_missing_capabilities_by_users([['id' => $data->userid]], $data->serviceid); 166 167 if ($data->serviceshortname <> MOODLE_OFFICIAL_MOBILE_SERVICE && !is_siteadmin($data->userid) 168 && array_key_exists($data->userid, $usermissingcaps)) { 169 $count = \html_writer::span(count($usermissingcaps[$data->userid]), 'badge badge-danger'); 170 $links = array_map(function($capname) { 171 return get_capability_docs_link((object)['name' => $capname]) . \html_writer::div($capname, 'text-muted'); 172 }, $usermissingcaps[$data->userid]); 173 $list = \html_writer::alist($links); 174 $help = $OUTPUT->help_icon('missingcaps', 'webservice'); 175 $content .= print_collapsible_region(\html_writer::div($list . $help, 'missingcaps'), 'small mt-2', 176 \html_writer::random_id('usermissingcaps'), get_string('usermissingcaps', 'webservice', $count), '', true, true); 177 } 178 179 return $content; 180 } 181 182 /** 183 * Generate the token column. 184 * 185 * @param \stdClass $data Data for the current row 186 * @return string Content for the column 187 */ 188 public function col_token($data) { 189 global $USER; 190 // Hide the token if it wasn't created by the current user. 191 if ($data->creatorid != $USER->id) { 192 return \html_writer::tag('small', get_string('onlyseecreatedtokens', 'core_webservice'), ['class' => 'text-muted']); 193 } 194 195 return $data->token; 196 } 197 198 /** 199 * Generate the creator column. 200 * 201 * @param \stdClass $data 202 * @return string 203 */ 204 public function col_creatorlastname($data) { 205 // We have loaded all the name fields for the creator, with the 'creator' prefix. 206 // So just remove the prefix and make up a user object. 207 $user = []; 208 foreach ($data as $key => $value) { 209 if (strpos($key, 'creator') !== false) { 210 $newkey = str_replace('creator', '', $key); 211 $user[$newkey] = $value; 212 } 213 } 214 215 $creatorprofileurl = new \moodle_url('/user/profile.php', ['id' => $data->creatorid]); 216 return \html_writer::link($creatorprofileurl, fullname((object)$user, $this->hasviewfullnames)); 217 } 218 219 /** 220 * Format the service name column. 221 * 222 * @param \stdClass $data 223 * @return string 224 */ 225 public function col_servicename($data) { 226 return \html_writer::div(s($data->servicename)) . \html_writer::div(s($data->serviceshortname), 'small text-muted'); 227 } 228 229 /** 230 * This function is used for the extra user fields. 231 * 232 * These are being dynamically added to the table so there are no functions 'col_<userfieldname>' as 233 * the list has the potential to increase in the future and we don't want to have to remember to add 234 * a new method to this class. We also don't want to pollute this class with unnecessary methods. 235 * 236 * @param string $colname The column name 237 * @param \stdClass $data 238 * @return string 239 */ 240 public function other_cols($colname, $data) { 241 return s($data->{$colname}); 242 } 243 244 /** 245 * Query the database for results to display in the table. 246 * 247 * Note: Initial bars are not implemented for this table because it includes user details twice and the initial bars do not work 248 * when the user table is included more than once. 249 * 250 * @param int $pagesize size of page for paginated displayed table. 251 * @param bool $useinitialsbar Not implemented. Please pass false. 252 */ 253 public function query_db($pagesize, $useinitialsbar = false) { 254 global $DB, $USER; 255 256 if ($useinitialsbar) { 257 debugging('Initial bar not implemented yet. Call out($pagesize, false)'); 258 } 259 260 $userfieldsapi = \core_user\fields::for_name(); 261 $usernamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects; 262 $creatorfields = $userfieldsapi->get_sql('c', false, 'creator', '', false)->selects; 263 264 if (!empty($this->userextrafields)) { 265 $usernamefields .= ',u.' . implode(',u.', $this->userextrafields); 266 } 267 268 $params = ['tokenmode' => EXTERNAL_TOKEN_PERMANENT]; 269 270 $selectfields = "SELECT t.id, t.token, t.iprestriction, t.validuntil, t.creatorid, 271 u.id AS userid, $usernamefields, 272 s.id AS serviceid, s.name AS servicename, s.shortname AS serviceshortname, 273 $creatorfields "; 274 275 $selectcount = "SELECT COUNT(t.id) "; 276 277 $sql = " FROM {external_tokens} t 278 JOIN {user} u ON u.id = t.userid 279 JOIN {external_services} s ON s.id = t.externalserviceid 280 JOIN {user} c ON c.id = t.creatorid 281 WHERE t.tokentype = :tokenmode"; 282 283 if (!$this->showalltokens) { 284 // Only show tokens created by the current user. 285 $sql .= " AND t.creatorid = :userid"; 286 $params['userid'] = $USER->id; 287 } 288 289 if ($this->filterdata->token !== '') { 290 $sql .= " AND " . $DB->sql_like("t.token", ":token"); 291 $params['token'] = "%" . $DB->sql_like_escape($this->filterdata->token) . "%"; 292 } 293 294 if (!empty($this->filterdata->users)) { 295 list($sqlusers, $paramsusers) = $DB->get_in_or_equal($this->filterdata->users, SQL_PARAMS_NAMED, 'user'); 296 $sql .= " AND t.userid {$sqlusers}"; 297 $params += $paramsusers; 298 } 299 300 if (!empty($this->filterdata->services)) { 301 list($sqlservices, $paramsservices) = $DB->get_in_or_equal($this->filterdata->services, SQL_PARAMS_NAMED, 'service'); 302 $sql .= " AND s.id {$sqlservices}"; 303 $params += $paramsservices; 304 } 305 306 $sort = $this->get_sql_sort(); 307 $sortsql = ''; 308 309 if ($sort) { 310 $sortsql = " ORDER BY {$sort}"; 311 } 312 313 $total = $DB->count_records_sql($selectcount . $sql, $params); 314 $this->pagesize($pagesize, $total); 315 316 $this->rawdata = $DB->get_recordset_sql($selectfields . $sql . $sortsql, $params, $this->get_page_start(), 317 $this->get_page_size()); 318 } 319 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body