MDL-46567 gradereport_history: Move paging implementation to db layer

Part of MDL-46191
This commit is contained in:
Luke Tucker 2014-07-10 15:23:00 +09:30 committed by Ankit Agarwal
parent 6cbd548061
commit d94d6e829a
5 changed files with 144 additions and 133 deletions

View File

@ -77,6 +77,10 @@ $mform = new gradereport_history_filter_form(null, $params);
$filters = array();
if ($data = $mform->get_data()) {
$filters = (array)$data;
if (!empty($filters['datetill'])) {
$filters['datetill'] += DAYSECS - 1; // Set to end of the chosen day.
}
} else {
$filters = array(
'id' => $courseid,
@ -88,9 +92,8 @@ if ($data = $mform->get_data()) {
'revisedonly' => optional_param('revisedonly', 0, PARAM_INT),
);
}
if (!empty($filters['datetill'])) {
$filters['datetill'] += DAYSECS - 1; // Set to end of the chosen day.
}
$report = new grade_report_history($courseid, $gpr, $context, $filters, $page, $sortitemid);
@ -123,7 +126,7 @@ $reportname = $output->report_title($report->get_selected_users());
// Print header.
print_grade_page_head($COURSE->id, 'report', 'history', $reportname, false, '');
if (!empty($report->perpage)) {
if (!empty($report->perpage) && $report->perpage < $report->numrows) {
echo $OUTPUT->paging_bar($numrows, $report->page, $report->perpage, $report->pbarurl);
}
@ -131,7 +134,7 @@ $mform->display();
echo $historytable;
// Prints paging bar at bottom for large pages.
if (!empty($report->perpage) && $report->perpage >= 20) {
if (!empty($report->perpage) && $report->perpage < $report->numrows) {
echo $OUTPUT->paging_bar($numrows, $report->page, $report->perpage, $report->pbarurl);
}
echo $OUTPUT->footer();

View File

@ -38,6 +38,8 @@ $string['gradeold'] = 'Original grade';
$string['grader'] = 'Grader';
$string['history:manage'] = 'Manage the grade history';
$string['history:view'] = 'View the grade history';
$string['historyperpage'] = 'History entries per page';
$string['historyperpage_help'] = 'This setting determines the number of history entries displayed per page in the history report.';
$string['locked'] = 'Locked';
$string['overridden'] = 'Overridden';
$string['pluginname'] = 'Grade history';

View File

@ -37,8 +37,22 @@ class grade_report_history extends grade_report {
private $history;
private $itemidmap = array();
/**
* Current page (for paging).
* @var int $page
*/
public $page = 0;
/**
* Number of history rows per page.
* @var string $perpage
*/
public $perpage = 50;
/**
* Total number of history rows.
* @var string $numrows
*/
public $numrows = 0;
/**
@ -88,6 +102,7 @@ class grade_report_history extends grade_report {
unset($urlparams['submitbutton']);
unset($urlparams['userfullnames']);
$this->pbarurl = new moodle_url('/grade/report/history/index.php', $urlparams);
$this->perpage = $this->get_pref('historyperpage');
$this->setup_sortitemid();
}
@ -100,10 +115,33 @@ class grade_report_history extends grade_report {
$coursecontext = $this->context->get_course_context(true);
$fields = 'ggh.*, gi.itemname, gi.itemtype, gi.itemmodule, gi.iteminstance, gi.itemnumber';
$fields = 'ggh.timemodified, ggh.itemid, ggh.userid, ggh.finalgrade, ggh.usermodified,
ggh.source, ggh.overridden, ggh.locked, ggh.excluded, ggh.feedback,
gi.itemtype, gi.itemmodule, gi.iteminstance, gi.itemnumber';
$select = $count ? 'COUNT(1)' : $fields;
$order = $count ? '' : 'ORDER BY ggh.id ASC';
if ($this->sortitemid == 'firstname' || $this->sortitemid == 'lastname' || $this->sortitemid == 'username' || $this->sortitemid == 'email') {
$sortitemid = 'u.' . $this->sortitemid;
$fields .= ', u.' . $this->sortitemid;
} else if ($this->sortitemid == 'grader') {
$sortitemid = 'ug.firstname, ug.lastname';
$fields .= ', ug.firstname, ug.lastname';
} else {
$sortitemid = $this->sortitemid;
}
if (!$count) {
// Max removes duplicates. Aliased and conditional fields added here.
$select = 'MAX(ggh.id) AS id, ' . $fields . ',
ggh2.finalgrade AS prevgrade,
CASE WHEN gi.itemname IS NULL THEN gi.itemtype ELSE gi.itemname END AS itemname';
} else {
$select = 'COUNT(1)';
}
// Group by removes duplicates, non-aliased fields added here.
$groupby = 'GROUP BY '.$fields. ', ggh2.finalgrade, gi.itemname';
$order = $count ? '' : 'ORDER BY ' . $sortitemid . ' ' . $this->sortorder;
$params = array(
'courseid' => $coursecontext->instanceid,
);
@ -118,16 +156,43 @@ class grade_report_history extends grade_report {
$filter .= " AND ggh.userid $insql";
$params += $plist;
}
if (!empty($this->filters['datefrom'])) {
$filter .= " AND ggh.timemodified >= :datefrom";
$params += array('datefrom' => $this->filters['datefrom']);
}
if (!empty($this->filters['datetill'])) {
$filter .= " AND ggh.timemodified <= :datetill";
$params += array('datetill' => $this->filters['datetill']);
}
if (!empty($this->filters['grader'])) {
$filter .= " AND ggh.usermodified = :grader";
$params += array('grader' => $this->filters['grader']);
}
if (!empty($this->filters['revisedonly'])) {
$filter .= " AND (ggh.finalgrade != ggh2.finalgrade
OR (ggh2.finalgrade IS NULL AND ggh.finalgrade IS NOT NULL)
OR (ggh2.finalgrade IS NOT NULL AND ggh.finalgrade IS NULL))";
}
$sql = "SELECT $select
FROM {grade_grades_history} ggh
JOIN {grade_items} gi ON gi.id = ggh.itemid
LEFT JOIN {grade_grades_history} ggh2 ON ggh2.id = (SELECT MAX(h.id)
FROM {grade_grades_history} h
WHERE h.itemid = ggh.itemid
AND h.userid = ggh.userid
AND (h.id < ggh.id))
JOIN {user} u ON u.id = ggh.userid
JOIN {user} ug ON ug.id = ggh.usermodified
WHERE gi.courseid = :courseid $filter
$groupby
$order";
if ($count) {
return $DB->count_records_sql($sql, $params);
$countsql = "SELECT COUNT(1) FROM ($sql) res";
return $DB->count_records_sql($countsql, $params);
}
if (!$this->history = $DB->get_records_sql($sql, $params)) {
if (!$this->history = $DB->get_records_sql($sql, $params, $this->perpage * $this->page, $this->perpage)) {
return $this->history;
}
@ -137,17 +202,6 @@ class grade_report_history extends grade_report {
$modifiers[$record->usermodified] = true;
}
$this->itemidmap[$record->itemid][$record->userid][] = $record->id;
$record->display = true;
if (!empty($this->filters['datefrom']) && $record->timemodified < $this->filters['datefrom']) {
$record->display = false;
}
if (!empty($this->filters['datetill']) && $record->timemodified > $this->filters['datetill']) {
$record->display = false;
}
if (!empty($this->filters['grader']) && $record->usermodified != $this->filters['grader']) {
$record->display = false;
}
}
if ($users = $DB->get_records_list('user', 'id', array_keys($modifiers), '', 'id,username,firstname,lastname,email')) {
$this->users += $users;
@ -156,54 +210,6 @@ class grade_report_history extends grade_report {
return $this->history;
}
protected function sort_table(&$rows) {
$sort = $this->sortorder == 'ASC' ? SORT_ASC : SORT_DESC;
if ($this->sortitemid == 'datetime') {
if ($this->sortorder == 'ASC') {
return;
}
krsort($rows);
return;
}
if ($this->sortitemid == 'firstname' || $this->sortitemid == 'lastname') {
$values = array();
foreach ($rows as $row) {
$values[] = $row->cells[$this->fieldorder['studentname']]->attributes["data-$this->sortitemid"];
}
array_multisort($values, $sort, $rows);
return;
}
$values = array();
foreach ($rows as $row) {
$values[] = $row->cells[$this->fieldorder[$this->sortitemid]];
}
array_multisort($values, $sort, $rows);
}
/**
* @param int $id The id in the history table you want to find the
* history of.
*/
protected function get_previous_record($id) {
if (!isset($this->itemidmap[$this->history[$id]->itemid][$this->history[$id]->userid])) {
return null;
}
$list = $this->itemidmap[$this->history[$id]->itemid][$this->history[$id]->userid];
$prev = false;
foreach ($list as $value) {
if ($value == $id) {
if ($prev) {
return $this->history[$prev];
}
return null;
}
$prev = $value;
}
return null;
}
public function get_table_data() {
$list = array();
@ -364,23 +370,13 @@ class grade_report_history extends grade_report {
$gitems = grade_item::fetch_all(array('courseid' => $this->context->instanceid));
foreach ($data as $record) {
if (!$record->display) {
continue;
}
$previous = $this->get_previous_record($record->id);
$previousgrade = is_null($previous) ? '' : $previous->finalgrade;
if ($this->filters['revisedonly'] && $previousgrade == $record->finalgrade) {
continue;
}
$row = new html_table_row();
$row->cells[] = userdate($record->timemodified, '%d/%m/%Y %H:%M');
$row->cells[] = $gitems[$record->itemid]->get_name();
$row->cells[] = $this->users[$record->userid]->username;
$row->cells[] = $previousgrade;
$row->cells[] = $record->prevgrade;
$row->cells[] = $record->finalgrade;
foreach ($extrafields as $field) {
// BASE-445 - do not show an additional username column
@ -407,26 +403,11 @@ class grade_report_history extends grade_report {
$row->cells[] = $record->feedback;
$rows[] = $row;
}
$this->sort_table($rows);
// Prune duplicate rows. Gradebook likes to have several history rows
// for the same action.
$lastrow = null;
foreach ($rows as $key => $row) {
if ($lastrow == $row) {
unset($rows[$key]);
}
$lastrow = $row;
}
$this->numrows = count($rows);
array_unshift($rows, null);
$rows = array_slice($rows, $this->perpage * $this->page, $this->perpage + 1);
$fulltable->data += $rows;
$html .= html_writer::table($fulltable);
$this->tabledata = $rows;
$this->numrows = $this->get_history(true);
$fulltable->data = array_merge($fulltable->data, $rows);
$html .= html_writer::table($fulltable);
return $OUTPUT->container($html, 'gradeparent');
}
@ -440,7 +421,7 @@ class grade_report_history extends grade_report {
// TODO: build list of fields, then sort at end.
// Sortable items.
$items = array('datetime', 'gradeitem', 'username');
$items = array('timemodified', 'itemname', 'username', 'prevgrade', 'finalgrade');
foreach ($items as $item) {
$header = new html_table_cell();
$header->attributes['class'] = 'header';
@ -451,18 +432,6 @@ class grade_report_history extends grade_report {
$headerrow->cells[] = $header;
}
// Non-sorting items.
$items = array('gradeold', 'gradenew');
foreach ($items as $item) {
$header = new html_table_cell();
$header->attributes['class'] = 'header';
$header->scope = 'col';
$header->header = true;
$header->id = $item.'header';
$header->text = $this->get_lang_string($item, 'gradereport_history');
$headerrow->cells[] = $header;
}
foreach ($extrafields as $field) {
// BASE-445 - do not show an additional username column
if ($field == 'username') {
@ -479,7 +448,7 @@ class grade_report_history extends grade_report {
}
// More sortable items.
$items = array('studentname', 'grader');
$items = array('studentname', 'grader', 'source', 'overridden', 'locked', 'excluded', 'feedback');
foreach ($items as $item) {
$header = new html_table_cell();
$header->attributes['class'] = 'header';
@ -490,18 +459,6 @@ class grade_report_history extends grade_report {
$headerrow->cells[] = $header;
}
// Non-sorting items.
$items = array('source', 'overridden', 'locked', 'excluded', 'feedbacktext');
foreach ($items as $item) {
$header = new html_table_cell();
$header->attributes['class'] = 'header';
$header->scope = 'col';
$header->header = true;
$header->id = $item.'header';
$header->text = html_writer::tag('p', $this->get_lang_string($item, 'gradereport_history'));
$headerrow->cells[] = $header;
}
$i = 0;
foreach ($headerrow->cells as &$cell) {
$name = substr($cell->id, 0, strlen($cell->id) - 6);
@ -554,19 +511,35 @@ class grade_report_history extends grade_report {
$strdatetime = $this->get_lang_string('datetime', 'gradereport_history');
$strgradeitem = $this->get_lang_string('gradeitem', 'grades');
$strgrader = $this->get_lang_string('grader', 'gradereport_history');
$strgradeold = $this->get_lang_string('gradeold', 'gradereport_history');
$strgradenew = $this->get_lang_string('gradenew', 'gradereport_history');
$strsource = $this->get_lang_string('source', 'gradereport_history');
$stroverride = $this->get_lang_string('overridden', 'gradereport_history');
$strlocked = $this->get_lang_string('locked', 'gradereport_history');
$strexcluded = $this->get_lang_string('excluded', 'gradereport_history');
$strfeedback = $this->get_lang_string('feedbacktext', 'gradereport_history');
$iconasc = $OUTPUT->pix_icon('t/sort_asc', $strsortasc, '', array('class' => 'iconsmall sorticon'));
$icondesc = $OUTPUT->pix_icon('t/sort_desc', $strsortdesc, '', array('class' => 'iconsmall sorticon'));
$firstlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'firstname')), $strfirstname);
$lastlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'lastname')), $strlastname);
$firstlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'firstname')), $strfirstname);
$lastlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'lastname')), $strlastname);
$datetimelink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'datetime')), $strdatetime);
$usernamelink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'username')), $strusername);
$gradeitemlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'gradeitem')), $strgradeitem);
$graderlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid' => 'grader')), $strgrader);
$timemodifiedlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'timemodified')), $strdatetime);
$usernamelink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'username')), $strusername);
$itemnamelink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'itemname')), $strgradeitem);
$graderlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'grader')), $strgrader);
$finalgradelink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'finalgrade')), $strgradenew);
$prevgradelink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'prevgrade')), $strgradeold);
$sourcelink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'source')), $strsource);
$overriddenlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'overridden')), $stroverride);
$lockedlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'locked')), $strlocked);
$excludedlink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'excluded')), $strexcluded);
$feedbacklink = html_writer::link(new moodle_url($this->pbarurl, array('sortitemid' => 'feedback')), $strfeedback);
$stditems = array('datetime', 'username', 'gradeitem', 'grader');
$stditems = array('timemodified', 'username', 'itemname', 'grader', 'prevgrade', 'finalgrade',
'source', 'overridden', 'locked', 'excluded', 'feedback');
foreach ($stditems as $item) {
$arrows[$item] = ${"{$item}link"};
if ($this->sortitemid === $item) {
@ -599,7 +572,7 @@ class grade_report_history extends grade_report {
}
foreach ($extrafields as $field) {
$fieldlink = html_writer::link(new moodle_url($this->baseurl,
$fieldlink = html_writer::link(new moodle_url($this->pbarurl,
array('sortitemid' => $field)), get_user_field_name($field));
$arrows[$field] = $fieldlink;

View File

@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Defines site config settings for the grade history report
*
* @package gradereport_history
* @copyright 2014 NetSpot Pty Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
/// Add settings for this module to the $settings object (it's already defined)
$settings->add(new admin_setting_configtext('grade_report_historyperpage', get_string('historyperpage', 'gradereport_history'),
get_string('historyperpage_help', 'gradereport_history'), 50));
}

View File

@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2013121600;
$plugin->version = 2014070900;
$plugin->requires = 2013051402;
$plugin->component = 'gradereport_history';