[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 class mod_feedback_responses_table 19 * 20 * @package mod_feedback 21 * @copyright 2016 Marina Glancy 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 global $CFG; 28 require_once($CFG->libdir . '/tablelib.php'); 29 30 /** 31 * Class mod_feedback_responses_table 32 * 33 * @package mod_feedback 34 * @copyright 2016 Marina Glancy 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class mod_feedback_responses_table extends table_sql { 38 39 /** @var mod_feedback_structure */ 40 protected $feedbackstructure; 41 42 /** @var int */ 43 protected $grandtotal = null; 44 45 /** @var bool */ 46 protected $showall = false; 47 48 /** @var string */ 49 protected $showallparamname = 'showall'; 50 51 /** @var string */ 52 protected $downloadparamname = 'download'; 53 54 /** 55 * Constructor 56 * 57 * @param mod_feedback_structure $feedbackstructure 58 */ 59 public function __construct(mod_feedback_structure $feedbackstructure) { 60 $this->feedbackstructure = $feedbackstructure; 61 62 parent::__construct('feedback-showentry-list-' . $feedbackstructure->get_cm()->instance); 63 64 $this->showall = optional_param($this->showallparamname, 0, PARAM_BOOL); 65 $this->define_baseurl(new moodle_url('/mod/feedback/show_entries.php', 66 ['id' => $this->feedbackstructure->get_cm()->id])); 67 if ($courseid = $this->feedbackstructure->get_courseid()) { 68 $this->baseurl->param('courseid', $courseid); 69 } 70 if ($this->showall) { 71 $this->baseurl->param($this->showallparamname, $this->showall); 72 } 73 74 $name = format_string($feedbackstructure->get_feedback()->name); 75 $this->is_downloadable(true); 76 $this->is_downloading(optional_param($this->downloadparamname, 0, PARAM_ALPHA), 77 $name, get_string('responses', 'feedback')); 78 $this->useridfield = 'userid'; 79 $this->init(); 80 } 81 82 /** 83 * Initialises table 84 */ 85 protected function init() { 86 87 $tablecolumns = array('userpic', 'fullname'); 88 $tableheaders = array(get_string('userpic'), get_string('fullnameuser')); 89 90 $extrafields = get_extra_user_fields($this->get_context()); 91 $ufields = user_picture::fields('u', $extrafields, $this->useridfield); 92 $fields = 'c.id, c.timemodified as completed_timemodified, c.courseid, '.$ufields; 93 $from = '{feedback_completed} c ' 94 . 'JOIN {user} u ON u.id = c.userid AND u.deleted = :notdeleted'; 95 $where = 'c.anonymous_response = :anon 96 AND c.feedback = :instance'; 97 if ($this->feedbackstructure->get_courseid()) { 98 $where .= ' AND c.courseid = :courseid'; 99 } 100 101 if ($this->is_downloading()) { 102 // When downloading data: 103 // Remove 'userpic' from downloaded data. 104 array_shift($tablecolumns); 105 array_shift($tableheaders); 106 107 // Add all identity fields as separate columns. 108 foreach ($extrafields as $field) { 109 $fields .= ", u.{$field}"; 110 $tablecolumns[] = $field; 111 $tableheaders[] = get_user_field_name($field); 112 } 113 } 114 115 if ($this->feedbackstructure->get_feedback()->course == SITEID && !$this->feedbackstructure->get_courseid()) { 116 $tablecolumns[] = 'courseid'; 117 $tableheaders[] = get_string('course'); 118 } 119 120 $tablecolumns[] = 'completed_timemodified'; 121 $tableheaders[] = get_string('date'); 122 123 $this->define_columns($tablecolumns); 124 $this->define_headers($tableheaders); 125 126 $this->sortable(true, 'lastname', SORT_ASC); 127 $this->collapsible(true); 128 $this->set_attribute('id', 'showentrytable'); 129 130 $params = array(); 131 $params['anon'] = FEEDBACK_ANONYMOUS_NO; 132 $params['instance'] = $this->feedbackstructure->get_feedback()->id; 133 $params['notdeleted'] = 0; 134 $params['courseid'] = $this->feedbackstructure->get_courseid(); 135 136 $group = groups_get_activity_group($this->feedbackstructure->get_cm(), true); 137 if ($group) { 138 $where .= ' AND c.userid IN (SELECT g.userid FROM {groups_members} g WHERE g.groupid = :group)'; 139 $params['group'] = $group; 140 } 141 142 $this->set_sql($fields, $from, $where, $params); 143 $this->set_count_sql("SELECT COUNT(c.id) FROM $from WHERE $where", $params); 144 } 145 146 /** 147 * Current context 148 * @return context_module 149 */ 150 protected function get_context() { 151 return context_module::instance($this->feedbackstructure->get_cm()->id); 152 } 153 154 /** 155 * Allows to set the display column value for all columns without "col_xxxxx" method. 156 * @param string $column column name 157 * @param stdClass $row current record result of SQL query 158 */ 159 public function other_cols($column, $row) { 160 if (preg_match('/^val(\d+)$/', $column, $matches)) { 161 $items = $this->feedbackstructure->get_items(); 162 $itemobj = feedback_get_item_class($items[$matches[1]]->typ); 163 return trim($itemobj->get_printval($items[$matches[1]], (object) ['value' => $row->$column] )); 164 } 165 return $row->$column; 166 } 167 168 /** 169 * Prepares column userpic for display 170 * @param stdClass $row 171 * @return string 172 */ 173 public function col_userpic($row) { 174 global $OUTPUT; 175 $user = user_picture::unalias($row, [], $this->useridfield); 176 return $OUTPUT->user_picture($user, array('courseid' => $this->feedbackstructure->get_cm()->course)); 177 } 178 179 /** 180 * Prepares column deleteentry for display 181 * @param stdClass $row 182 * @return string 183 */ 184 public function col_deleteentry($row) { 185 global $OUTPUT; 186 $deleteentryurl = new moodle_url($this->baseurl, ['delete' => $row->id, 'sesskey' => sesskey()]); 187 $deleteaction = new confirm_action(get_string('confirmdeleteentry', 'feedback')); 188 return $OUTPUT->action_icon($deleteentryurl, 189 new pix_icon('t/delete', get_string('delete_entry', 'feedback')), $deleteaction); 190 } 191 192 /** 193 * Returns a link for viewing a single response 194 * @param stdClass $row 195 * @return \moodle_url 196 */ 197 protected function get_link_single_entry($row) { 198 return new moodle_url($this->baseurl, ['userid' => $row->{$this->useridfield}, 'showcompleted' => $row->id]); 199 } 200 201 /** 202 * Prepares column completed_timemodified for display 203 * @param stdClass $student 204 * @return string 205 */ 206 public function col_completed_timemodified($student) { 207 if ($this->is_downloading()) { 208 return userdate($student->completed_timemodified); 209 } else { 210 return html_writer::link($this->get_link_single_entry($student), 211 userdate($student->completed_timemodified)); 212 } 213 } 214 215 /** 216 * Prepares column courseid for display 217 * @param array $row 218 * @return string 219 */ 220 public function col_courseid($row) { 221 $courses = $this->feedbackstructure->get_completed_courses(); 222 $name = ''; 223 if (isset($courses[$row->courseid])) { 224 $name = $courses[$row->courseid]; 225 if (!$this->is_downloading()) { 226 $name = html_writer::link(course_get_url($row->courseid), $name); 227 } 228 } 229 return $name; 230 } 231 232 /** 233 * Adds common values to the table that do not change the number or order of entries and 234 * are only needed when outputting or downloading data. 235 */ 236 protected function add_all_values_to_output() { 237 $tablecolumns = array_keys($this->columns); 238 $tableheaders = $this->headers; 239 240 // Add all feedback response values. 241 $items = $this->feedbackstructure->get_items(true); 242 foreach ($items as $nr => $item) { 243 $this->sql->fields .= ", v{$nr}.value AS val{$nr}"; 244 $this->sql->from .= " LEFT OUTER JOIN {feedback_value} v{$nr} " . 245 "ON v{$nr}.completed = c.id AND v{$nr}.item = :itemid{$nr}"; 246 $this->sql->params["itemid{$nr}"] = $item->id; 247 $tablecolumns[] = "val{$nr}"; 248 $itemobj = feedback_get_item_class($item->typ); 249 $tableheaders[] = $itemobj->get_display_name($item); 250 } 251 252 // Add 'Delete entry' column. 253 if (!$this->is_downloading() && has_capability('mod/feedback:deletesubmissions', $this->get_context())) { 254 $tablecolumns[] = 'deleteentry'; 255 $tableheaders[] = ''; 256 } 257 258 $this->define_columns($tablecolumns); 259 $this->define_headers($tableheaders); 260 } 261 262 /** 263 * Query the db. Store results in the table object for use by build_table. 264 * 265 * @param int $pagesize size of page for paginated displayed table. 266 * @param bool $useinitialsbar do you want to use the initials bar. Bar 267 * will only be used if there is a fullname column defined for the table. 268 */ 269 public function query_db($pagesize, $useinitialsbar=true) { 270 global $DB; 271 $this->totalrows = $grandtotal = $this->get_total_responses_count(); 272 if (!$this->is_downloading()) { 273 $this->initialbars($useinitialsbar); 274 275 list($wsql, $wparams) = $this->get_sql_where(); 276 if ($wsql) { 277 $this->countsql .= ' AND '.$wsql; 278 $this->countparams = array_merge($this->countparams, $wparams); 279 280 $this->sql->where .= ' AND '.$wsql; 281 $this->sql->params = array_merge($this->sql->params, $wparams); 282 283 $this->totalrows = $DB->count_records_sql($this->countsql, $this->countparams); 284 } 285 286 if ($this->totalrows > $pagesize) { 287 $this->pagesize($pagesize, $this->totalrows); 288 } 289 } 290 291 if ($sort = $this->get_sql_sort()) { 292 $sort = "ORDER BY $sort"; 293 } 294 $sql = "SELECT 295 {$this->sql->fields} 296 FROM {$this->sql->from} 297 WHERE {$this->sql->where} 298 {$sort}"; 299 300 if (!$this->is_downloading()) { 301 $this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size()); 302 } else { 303 $this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params); 304 } 305 } 306 307 /** 308 * Returns total number of reponses (without any filters applied) 309 * @return int 310 */ 311 public function get_total_responses_count() { 312 global $DB; 313 if ($this->grandtotal === null) { 314 $this->grandtotal = $DB->count_records_sql($this->countsql, $this->countparams); 315 } 316 return $this->grandtotal; 317 } 318 319 /** 320 * Defines columns 321 * @param array $columns an array of identifying names for columns. If 322 * columns are sorted then column names must correspond to a field in sql. 323 */ 324 public function define_columns($columns) { 325 parent::define_columns($columns); 326 foreach ($this->columns as $column => $column) { 327 // Automatically assign classes to columns. 328 $this->column_class[$column] = ' ' . $column; 329 } 330 } 331 332 /** 333 * Convenience method to call a number of methods for you to display the 334 * table. 335 * @param int $pagesize 336 * @param bool $useinitialsbar 337 * @param string $downloadhelpbutton 338 */ 339 public function out($pagesize, $useinitialsbar, $downloadhelpbutton='') { 340 $this->add_all_values_to_output(); 341 parent::out($pagesize, $useinitialsbar, $downloadhelpbutton); 342 } 343 344 /** 345 * Displays the table 346 */ 347 public function display() { 348 global $OUTPUT; 349 groups_print_activity_menu($this->feedbackstructure->get_cm(), $this->baseurl->out()); 350 $grandtotal = $this->get_total_responses_count(); 351 if (!$grandtotal) { 352 echo $OUTPUT->box(get_string('nothingtodisplay'), 'generalbox nothingtodisplay'); 353 return; 354 } 355 $this->out($this->showall ? $grandtotal : FEEDBACK_DEFAULT_PAGE_COUNT, 356 $grandtotal > FEEDBACK_DEFAULT_PAGE_COUNT); 357 358 // Toggle 'Show all' link. 359 if ($this->totalrows > FEEDBACK_DEFAULT_PAGE_COUNT) { 360 if (!$this->use_pages) { 361 echo html_writer::div(html_writer::link(new moodle_url($this->baseurl, [$this->showallparamname => 0]), 362 get_string('showperpage', '', FEEDBACK_DEFAULT_PAGE_COUNT)), 'showall'); 363 } else { 364 echo html_writer::div(html_writer::link(new moodle_url($this->baseurl, [$this->showallparamname => 1]), 365 get_string('showall', '', $this->totalrows)), 'showall'); 366 } 367 } 368 } 369 370 /** 371 * Returns links to previous/next responses in the list 372 * @param stdClass $record 373 * @return array array of three elements [$prevresponseurl, $returnurl, $nextresponseurl] 374 */ 375 public function get_reponse_navigation_links($record) { 376 $this->setup(); 377 $grandtotal = $this->get_total_responses_count(); 378 $this->query_db($grandtotal); 379 $lastrow = $thisrow = $nextrow = null; 380 $counter = 0; 381 $page = 0; 382 while ($this->rawdata->valid()) { 383 $row = $this->rawdata->current(); 384 if ($row->id == $record->id) { 385 $page = $this->showall ? 0 : floor($counter / FEEDBACK_DEFAULT_PAGE_COUNT); 386 $thisrow = $row; 387 $this->rawdata->next(); 388 $nextrow = $this->rawdata->valid() ? $this->rawdata->current() : null; 389 break; 390 } 391 $lastrow = $row; 392 $this->rawdata->next(); 393 $counter++; 394 } 395 $this->rawdata->close(); 396 if (!$thisrow) { 397 $lastrow = null; 398 } 399 return [ 400 $lastrow ? $this->get_link_single_entry($lastrow) : null, 401 new moodle_url($this->baseurl, [$this->request[TABLE_VAR_PAGE] => $page]), 402 $nextrow ? $this->get_link_single_entry($nextrow) : null, 403 ]; 404 } 405 406 /** 407 * Download the data. 408 */ 409 public function download() { 410 \core\session\manager::write_close(); 411 $this->out($this->get_total_responses_count(), false); 412 exit; 413 } 414 415 /** 416 * Returns html code for displaying "Download" button if applicable. 417 */ 418 public function download_buttons() { 419 global $OUTPUT; 420 421 if ($this->is_downloadable() && !$this->is_downloading()) { 422 return $OUTPUT->download_dataformat_selector(get_string('downloadas', 'table'), 423 $this->baseurl->out_omit_querystring(), $this->downloadparamname, $this->baseurl->params()); 424 } else { 425 return ''; 426 } 427 } 428 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |