Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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 * Task log table. 19 * 20 * @package core_admin 21 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_admin; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->libdir . '/tablelib.php'); 30 31 /** 32 * Table to display list of task logs. 33 * 34 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class task_log_table extends \table_sql { 38 39 /** 40 * Constructor for the task_log table. 41 * 42 * @param string $filter 43 * @param int $resultfilter 44 */ 45 public function __construct(string $filter = '', int $resultfilter = null) { 46 global $DB; 47 48 if (-1 === $resultfilter) { 49 $resultfilter = null; 50 } 51 52 parent::__construct('tasklogs'); 53 54 $columnheaders = [ 55 'classname' => get_string('name'), 56 'type' => get_string('tasktype', 'admin'), 57 'userid' => get_string('user', 'admin'), 58 'timestart' => get_string('task_starttime', 'admin'), 59 'duration' => get_string('task_duration', 'admin'), 60 'hostname' => get_string('hostname', 'tool_task'), 61 'pid' => get_string('pid', 'tool_task'), 62 'db' => get_string('task_dbstats', 'admin'), 63 'result' => get_string('task_result', 'admin'), 64 'actions' => '', 65 ]; 66 $this->define_columns(array_keys($columnheaders)); 67 $this->define_headers(array_values($columnheaders)); 68 69 // The name column is a header. 70 $this->define_header_column('classname'); 71 72 // This table is not collapsible. 73 $this->collapsible(false); 74 75 // The actions class should not wrap. Use the BS text utility class. 76 $this->column_class('actions', 'text-nowrap'); 77 78 // Allow pagination. 79 $this->pageable(true); 80 81 // Allow sorting. Default to sort by timestarted DESC. 82 $this->sortable(true, 'timestart', SORT_DESC); 83 84 // Add filtering. 85 $where = []; 86 $params = []; 87 if (!empty($filter)) { 88 $orwhere = []; 89 $filter = str_replace('\\', '\\\\', $filter); 90 91 // Check the class name. 92 $orwhere[] = $DB->sql_like('classname', ':classfilter', false, false); 93 $params['classfilter'] = '%' . $DB->sql_like_escape($filter) . '%'; 94 95 $orwhere[] = $DB->sql_like('output', ':outputfilter', false, false); 96 $params['outputfilter'] = '%' . $DB->sql_like_escape($filter) . '%'; 97 98 $where[] = "(" . implode(' OR ', $orwhere) . ")"; 99 } 100 101 if (null !== $resultfilter) { 102 $where[] = 'tl.result = :result'; 103 $params['result'] = $resultfilter; 104 } 105 106 $where = implode(' AND ', $where); 107 108 $this->set_sql('', '', $where, $params); 109 } 110 111 /** 112 * Query the db. Store results in the table object for use by build_table. 113 * 114 * @param int $pagesize size of page for paginated displayed table. 115 * @param bool $useinitialsbar do you want to use the initials bar. Bar 116 * will only be used if there is a fullname column defined for the table. 117 */ 118 public function query_db($pagesize, $useinitialsbar = true) { 119 global $DB; 120 121 // Fetch the attempts. 122 $sort = $this->get_sql_sort(); 123 if ($sort) { 124 $sort = "ORDER BY $sort"; 125 } 126 127 // TODO Does not support custom user profile fields (MDL-70456). 128 $userfieldsapi = \core_user\fields::for_identity(\context_system::instance(), false)->with_userpic(); 129 $userfields = $userfieldsapi->get_sql('u', false, 'user', 'userid2', false)->selects; 130 131 $where = ''; 132 if (!empty($this->sql->where)) { 133 $where = "WHERE {$this->sql->where}"; 134 } 135 136 $sql = "SELECT 137 tl.id, tl.type, tl.component, tl.classname, tl.userid, tl.timestart, tl.timeend, 138 tl.hostname, tl.pid, 139 tl.dbreads, tl.dbwrites, tl.result, 140 tl.dbreads + tl.dbwrites AS db, 141 tl.timeend - tl.timestart AS duration, 142 {$userfields} 143 FROM {task_log} tl 144 LEFT JOIN {user} u ON u.id = tl.userid 145 {$where} 146 {$sort}"; 147 148 $this->pagesize($pagesize, $DB->count_records_sql("SELECT COUNT('x') FROM {task_log} tl {$where}", $this->sql->params)); 149 if (!$this->is_downloading()) { 150 $this->rawdata = $DB->get_records_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size()); 151 } else { 152 $this->rawdata = $DB->get_records_sql($sql, $this->sql->params); 153 } 154 } 155 156 /** 157 * Format the name cell. 158 * 159 * @param \stdClass $row 160 * @return string 161 */ 162 public function col_classname($row) : string { 163 $output = ''; 164 if (class_exists($row->classname)) { 165 $task = new $row->classname; 166 if ($task instanceof \core\task\scheduled_task) { 167 $output = $task->get_name(); 168 } 169 } 170 171 $output .= \html_writer::tag('div', "\\{$row->classname}", [ 172 'class' => 'task-class', 173 ]); 174 return $output; 175 } 176 177 /** 178 * Format the type cell. 179 * 180 * @param \stdClass $row 181 * @return string 182 */ 183 public function col_type($row) : string { 184 if (\core\task\database_logger::TYPE_SCHEDULED == $row->type) { 185 return get_string('task_type:scheduled', 'admin'); 186 } else { 187 return get_string('task_type:adhoc', 'admin'); 188 } 189 } 190 191 /** 192 * Format the timestart cell. 193 * 194 * @param \stdClass $row 195 * @return string 196 */ 197 public function col_result($row) : string { 198 if ($row->result) { 199 return get_string('task_result:failed', 'admin'); 200 } else { 201 return get_string('success'); 202 } 203 } 204 205 /** 206 * Format the timestart cell. 207 * 208 * @param \stdClass $row 209 * @return string 210 */ 211 public function col_timestart($row) : string { 212 return userdate($row->timestart, get_string('strftimedatetimeshort', 'langconfig')); 213 } 214 215 /** 216 * Format the duration cell. 217 * 218 * @param \stdClass $row 219 * @return string 220 */ 221 public function col_duration($row) : string { 222 $duration = round($row->timeend - $row->timestart, 2); 223 224 if (empty($duration)) { 225 // The format_time function returns 'now' when the difference is exactly 0. 226 // Note: format_time performs concatenation in exactly this fashion so we should do this for consistency. 227 return '0 ' . get_string('secs', 'moodle'); 228 } 229 230 return format_time($duration); 231 } 232 233 /** 234 * Format the DB details cell. 235 * 236 * @param \stdClass $row 237 * @return string 238 */ 239 public function col_db($row) : string { 240 $output = ''; 241 242 $output .= \html_writer::div(get_string('task_stats:dbreads', 'admin', $row->dbreads)); 243 $output .= \html_writer::div(get_string('task_stats:dbwrites', 'admin', $row->dbwrites)); 244 245 return $output; 246 } 247 248 /** 249 * Format the actions cell. 250 * 251 * @param \stdClass $row 252 * @return string 253 */ 254 public function col_actions($row) : string { 255 global $OUTPUT; 256 257 $actions = []; 258 259 $url = new \moodle_url('/admin/tasklogs.php', ['logid' => $row->id]); 260 261 // Quick view. 262 $actions[] = $OUTPUT->action_icon( 263 $url, 264 new \pix_icon('e/search', get_string('view')), 265 new \popup_action('click', $url) 266 ); 267 268 // Download. 269 $actions[] = $OUTPUT->action_icon( 270 new \moodle_url($url, ['download' => true]), 271 new \pix_icon('t/download', get_string('download')) 272 ); 273 274 return implode(' ', $actions); 275 } 276 277 /** 278 * Format the user cell. 279 * 280 * @param \stdClass $row 281 * @return string 282 */ 283 public function col_userid($row) : string { 284 if (empty($row->userid)) { 285 return ''; 286 } 287 288 $user = (object) []; 289 username_load_fields_from_object($user, $row, 'user'); 290 291 return fullname($user); 292 } 293 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body