diff --git a/grade/lib.php b/grade/lib.php index 4c7e3f90c228f..54fcfe543190a 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -1722,15 +1722,15 @@ public function get_grade_analysis_icon(grade_grade $grade) { * Returns a link leading to the grade analysis page * * @param grade_grade $grade - * @param string $gradeanalysisstring Language string * @return string|null */ - public function get_grade_analysis_link(grade_grade $grade, string $gradeanalysisstring): ?string { + public function get_grade_analysis_link(grade_grade $grade): ?string { $url = $this->get_grade_analysis_url($grade); if (is_null($url)) { return null; } + $gradeanalysisstring = grade_helper::get_lang_string('gradeanalysis', 'grades'); return html_writer::link($url, $gradeanalysisstring, ['class' => 'dropdown-item', 'aria-label' => $gradeanalysisstring, 'role' => 'menuitem']); } @@ -1945,10 +1945,9 @@ public function get_edit_icon($element, $gpr, $returnactionmenulink = false) { * * @param array $element An array representing an element in the grade_tree * @param object $gpr A grade_plugin_return object - * @param array $langstrings Language strings * @return string|null */ - public function get_edit_link(array $element, object $gpr, array $langstrings): ?string { + public function get_edit_link(array $element, object $gpr): ?string { $url = null; $title = ''; if ((!has_capability('moodle/grade:manage', $this->context) && @@ -1967,7 +1966,7 @@ public function get_edit_link(array $element, object $gpr, array $langstrings): ['courseid' => $this->courseid, 'id' => $object->id]); } $url = $gpr->add_url_params($url); - $title = $langstrings[0]; + $title = grade_helper::get_lang_string('editgrade', 'grades'); } else if (($element['type'] == 'item') || ($element['type'] == 'categoryitem') || ($element['type'] == 'courseitem')) { if (empty($object->outcomeid) || empty($CFG->enableoutcomes)) { @@ -1978,12 +1977,12 @@ public function get_edit_link(array $element, object $gpr, array $langstrings): ['courseid' => $this->courseid, 'id' => $object->id]); } $url = $gpr->add_url_params($url); - $title = $langstrings[1]; + $title = grade_helper::get_lang_string('itemsedit', 'grades'); } else if ($element['type'] == 'category') { $url = new moodle_url('/grade/edit/tree/category.php', ['courseid' => $this->courseid, 'id' => $object->id]); $url = $gpr->add_url_params($url); - $title = $langstrings[2]; + $title = grade_helper::get_lang_string('categoryedit', 'grades'); } return html_writer::link($url, $title, ['class' => 'dropdown-item', 'aria-label' => $title, 'role' => 'menuitem']); @@ -2109,10 +2108,9 @@ public function get_hiding_icon($element, $gpr, $returnactionmenulink = false) { * * @param array $element An array representing an element in the grade_tree * @param object $gpr A grade_plugin_return object - * @param array $langstrings Language strings * @return string|null */ - public function get_hiding_link(array $element, object $gpr, array $langstrings): ?string { + public function get_hiding_link(array $element, object $gpr): ?string { if (!$element['object']->can_control_visibility() || !has_capability('moodle/grade:manage', $this->context) || !has_capability('moodle/grade:hide', $this->context)) { return null; @@ -2124,10 +2122,10 @@ public function get_hiding_link(array $element, object $gpr, array $langstrings) if ($element['object']->is_hidden()) { $url->param('action', 'show'); - $title = $langstrings[0]; + $title = grade_helper::get_lang_string('show'); } else { $url->param('action', 'hide'); - $title = $langstrings[1]; + $title = grade_helper::get_lang_string('hide'); } $url = html_writer::link($url, $title, @@ -2209,11 +2207,10 @@ public function get_locking_icon($element, $gpr) { * * @param array $element An array representing an element in the grade_tree * @param object $gpr A grade_plugin_return object - * @param array $langstrings Language strings * * @return string|null */ - public function get_locking_link(array $element, object $gpr, array $langstrings): ?string { + public function get_locking_link(array $element, object $gpr): ?string { if (has_capability('moodle/grade:manage', $this->context) && isset($element['object'])) { $title = ''; @@ -2226,19 +2223,19 @@ public function get_locking_link(array $element, object $gpr, array $langstrings $strparamobj = new stdClass(); $strparamobj->itemname = $element['object']->grade_item->get_name(true, true); $strnonunlockable = get_string('nonunlockableverbose', 'grades', $strparamobj); - $title = $langstrings[0]; + $title = grade_helper::get_lang_string('unlock', 'grades'); return html_writer::span($title, 'text-muted dropdown-item', ['title' => $strnonunlockable, 'aria-label' => $title, 'role' => 'menuitem']); } else if ($element['object']->is_locked()) { if (has_capability('moodle/grade:unlock', $this->context)) { - $title = $langstrings[0]; + $title = grade_helper::get_lang_string('unlock', 'grades'); $url->param('action', 'unlock'); } else { return null; } } else { if (has_capability('moodle/grade:lock', $this->context)) { - $title = $langstrings[1]; + $title = grade_helper::get_lang_string('lock', 'grades'); $url->param('action', 'lock'); } else { return null; @@ -2304,12 +2301,10 @@ public function get_calculation_icon($element, $gpr, $returnactionmenulink = fal * * @param array $element An array representing an element in the grade_tree * @param object $gpr A grade_plugin_return object - * @param string $editcalculationstrings Language string * * @return string|null */ - public function get_edit_calculation_link(array $element, object $gpr, - string $editcalculationstrings): ?string { + public function get_edit_calculation_link(array $element, object $gpr): ?string { if (has_capability('moodle/grade:manage', $this->context) && isset($element['object'])) { $object = $element['object']; @@ -2318,32 +2313,184 @@ public function get_edit_calculation_link(array $element, object $gpr, // Show calculation icon only when calculation possible. if (!$object->is_external_item() && ($isscale || $isvalue)) { + $editcalculationstring = grade_helper::get_lang_string('editcalculation', 'grades'); $url = new moodle_url('/grade/edit/tree/calculation.php', ['courseid' => $this->courseid, 'id' => $object->id]); $url = $gpr->add_url_params($url); - return html_writer::link($url, $editcalculationstrings, - ['class' => 'dropdown-item', 'aria-label' => $editcalculationstrings, 'role' => 'menuitem']); + return html_writer::link($url, $editcalculationstring, + ['class' => 'dropdown-item', 'aria-label' => $editcalculationstring, 'role' => 'menuitem']); } } return null; } /** - * Returns link to change category view mode. + * Sets status icons for the grade. * - * @param moodle_url $url Url to grader report page - * @param string $title Menu item title - * @param string $action View mode to change to - * @param bool $active Whether link is active in dropdown + * @param array $element array with grade item info + * @return string status icons container HTML + */ + public function set_grade_status_icons(array $element): string { + global $OUTPUT; + + $attributes = ['class' => 'text-muted']; + + $statusicons = ''; + if ($element['object']->is_hidden()) { + $statusicons .= $OUTPUT->pix_icon('i/show', grade_helper::get_lang_string('hidden', 'grades'), + 'moodle', $attributes); + } + + if ($element['object']->is_locked()) { + $statusicons .= $OUTPUT->pix_icon('i/lock', grade_helper::get_lang_string('locked', 'grades'), + 'moodle', $attributes); + } + + if ($element['object'] instanceof grade_grade) { + $grade = $element['object']; + if ($grade->is_overridden()) { + $statusicons .= $OUTPUT->pix_icon('i/overriden_grade', + grade_helper::get_lang_string('overridden', 'grades'), 'moodle', $attributes); + } + + if ($grade->is_excluded()) { + $statusicons .= $OUTPUT->pix_icon('i/excluded', grade_helper::get_lang_string('excluded', 'grades'), + 'moodle', $attributes); + } + } + + $class = 'grade_icons'; + if (isset($element['type']) && ($element['type'] == 'category')) { + $class = 'category_grade_icons'; + } + if ($statusicons) { + $statusicons = $OUTPUT->container($statusicons, $class); + } + return $statusicons; + } + + /** + * Returns an action menu for the grade. * - * @return string|null + * @param array $element Array with cell info. + * @param string $mode Mode - gradeitem or user + * @param grade_plugin_return $gpr + * @param moodle_url|null $baseurl + * @return string */ - public function get_category_view_mode_link(moodle_url $url, string $title, string $action, bool $active = false): ?string { - $urlnew = $url; - $urlnew->param('action', $action); - $active = $active ? 'true' : 'false'; - return html_writer::link($urlnew, $title, - ['class' => 'dropdown-item', 'aria-label' => $title, 'aria-current' => $active, 'role' => 'menuitem']); + public function get_cell_action_menu(array $element, string $mode, grade_plugin_return $gpr, + ?moodle_url $baseurl = null): string { + global $OUTPUT, $USER; + + $context = new stdClass(); + + if ($mode == 'gradeitem') { + $editable = true; + + if ($element['type'] == 'grade') { + $item = $element['object']->grade_item; + if ($item->is_course_item() || $item->is_category_item()) { + $editable = (bool)get_config('moodle', 'grade_overridecat');; + } + + if (!empty($USER->editing)) { + if ($editable) { + $context->editurl = $this->get_edit_link($element, $gpr); + } + $context->hideurl = $this->get_hiding_link($element, $gpr); + $context->lockurl = $this->get_locking_link($element, $gpr); + } + + $context->gradeanalysisurl = $this->get_grade_analysis_link($element['object']); + } else if (($element['type'] == 'item') || ($element['type'] == 'categoryitem') || + ($element['type'] == 'courseitem') || ($element['type'] == 'userfield')) { + + $context->datatype = 'item'; + + if ($element['type'] == 'item') { + $context = + grade_report::get_additional_context($this->context, $this->courseid, $element, $gpr, $mode, $context, true); + $context->advancedgradingurl = $this->get_advanced_grading_link($element, $gpr); + } + + if ($element['type'] == 'item') { + $context->divider1 = true; + } + + if (!empty($USER->editing)) { + if ($element['type'] !== 'userfield') { + $context->divider1 = true; + $context->divider2 = true; + } + + if ($element['type'] == 'item') { + $context->editurl = $this->get_edit_link($element, $gpr); + } + + $context->editcalculationurl = + $this->get_edit_calculation_link($element, $gpr); + + if (isset($element['object'])) { + $object = $element['object']; + if ($object->itemmodule !== 'quiz') { + $context->hideurl = $this->get_hiding_link($element, $gpr); + } + } + $context->lockurl = $this->get_locking_link($element, $gpr); + } + + // Sorting item. + if ($baseurl) { + $sortlink = $baseurl; + if (isset($element['object']->id)) { + $sortlink->param('sortitemid', $element['object']->id); + } else if ($element['type'] == 'userfield') { + $context->datatype = $element['name']; + $sortlink->param('sortitemid', $element['name']); + } + + if (($element['type'] == 'userfield') && ($element['name'] == 'fullname')) { + $sortlink->param('sortitemid', 'firstname'); + $context->ascendingfirstnameurl = $this->get_sorting_link($sortlink, $gpr); + $context->descendingfirstnameurl = $this->get_sorting_link($sortlink, $gpr, 'desc'); + + $sortlink->param('sortitemid', 'lastname'); + $context->ascendinglastnameurl = $this->get_sorting_link($sortlink, $gpr); + $context->descendinglastnameurl = $this->get_sorting_link($sortlink, $gpr, 'desc'); + } else { + $context->ascendingurl = $this->get_sorting_link($sortlink, $gpr); + $context->descendingurl = $this->get_sorting_link($sortlink, $gpr, 'desc'); + } + } + } else if ($element['type'] == 'category') { + $context->datatype = 'category'; + $mode = 'category'; + $context = grade_report::get_additional_context($this->context, $this->courseid, $element, $gpr, $mode, $context); + if (!empty($USER->editing)) { + $context->divider1 = true; + } + $context->editurl = $this->get_edit_link($element, $gpr); + $context->hideurl = $this->get_hiding_link($element, $gpr); + $context->lockurl = $this->get_locking_link($element, $gpr); + } + + if (isset($element['object'])) { + $context->dataid = $element['object']->id; + } else if ($element['type'] == 'userfield') { + $context->dataid = $element['name']; + } + } else if ($mode == 'user') { + $context->datatype = 'user'; + $context = grade_report::get_additional_context($this->context, $this->courseid, $element, $gpr, $mode, $context, true); + $context->dataid = $element['userid']; + } + + if (!empty($USER->editing) || isset($context->gradeanalysisurl) || isset($context->gradesonlyurl) + || isset($context->aggregatesonlyurl) || isset($context->fullmodeurl) || isset($context->reporturl0) + || isset($context->ascendingfirstnameurl) || isset($context->ascendingurl)) { + return $OUTPUT->render_from_template('core_grades/cellmenu', $context); + } + return ''; } /** @@ -2351,11 +2498,16 @@ public function get_category_view_mode_link(moodle_url $url, string $title, stri * * @param moodle_url $sortlink A base link for sorting * @param object $gpr A grade_plugin_return object - * @param string $title Language string * @param string $direction Direction od sorting * @return string */ - public function get_sorting_link(moodle_url $sortlink, object $gpr, string $title, string $direction = 'asc'): string { + public function get_sorting_link(moodle_url $sortlink, object $gpr, string $direction = 'asc'): string { + + if ($direction == 'asc') { + $title = grade_helper::get_lang_string('asc'); + } else { + $title = grade_helper::get_lang_string('desc'); + } $sortlink->param('sort', $direction); $gpr->add_url_params($sortlink); diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index ba1e18b07b8a3..25e01cbcebeae 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -658,7 +658,8 @@ public function get_left_rows($displayaverages) { $studentheader->header = true; $studentheader->id = 'studentheader'; $element = ['type' => 'userfield', 'name' => 'fullname']; - $studentheader->text = $arrows['studentname'] . $this->get_cell_action_menu($element, 'gradeitem'); + $studentheader->text = $arrows['studentname'] . + $this->gtree->get_cell_action_menu($element, 'gradeitem', $this->gpr, $this->baseurl); $headerrow->cells[] = $studentheader; @@ -668,7 +669,8 @@ public function get_left_rows($displayaverages) { $fieldheader->scope = 'col'; $fieldheader->header = true; $element = ['type' => 'userfield', 'name' => $field]; - $fieldheader->text = $arrows[$field] . $this->get_cell_action_menu($element, 'gradeitem'); + $fieldheader->text = $arrows[$field] . + $this->gtree->get_cell_action_menu($element, 'gradeitem', $this->gpr, $this->baseurl); $headerrow->cells[] = $fieldheader; } @@ -714,7 +716,7 @@ public function get_left_rows($displayaverages) { // when horizontally scrolling through the table contents (most noticeable when in RTL mode). // Therefore, add slight padding on the left or right when using RTL mode. $usercell->attributes['class'] .= ' pl-3'; - $usercell->text .= $this->get_cell_action_menu(['userid' => $userid], 'user'); + $usercell->text .= $this->gtree->get_cell_action_menu(['userid' => $userid], 'user', $this->gpr); $userrow->cells[] = $usercell; @@ -751,7 +753,8 @@ public function get_right_rows(bool $displayaverages) : array { $this->rowcount = 0; $numusers = count($this->users); $gradetabindex = 1; - $strgrade = $this->get_lang_string('gradenoun'); + $strgrade = \grade_helper::get_lang_string('gradenoun'); + $this->get_sort_arrows(); // Get preferences once. $quickgrading = $this->get_pref('quickgrading'); @@ -809,7 +812,7 @@ public function get_right_rows(bool $displayaverages) : array { $categorycell->header = true; $categorycell->scope = 'col'; - $statusicons = $this->set_grade_status_icons($element); + $statusicons = $this->gtree->set_grade_status_icons($element); if ($statusicons) { $categorycell->text .= $statusicons; $categorycell->attributes['class'] .= ' statusicons'; @@ -837,8 +840,8 @@ public function get_right_rows(bool $displayaverages) : array { ' highlightable'. ' i'. $element['object']->id; $itemcell->attributes['data-itemid'] = $element['object']->id; - $singleview = $this->get_cell_action_menu($element, 'gradeitem'); - $statusicons = $this->set_grade_status_icons($element); + $singleview = $this->gtree->get_cell_action_menu($element, 'gradeitem', $this->gpr, $this->baseurl); + $statusicons = $this->gtree->set_grade_status_icons($element); if ($statusicons) { $itemcell->attributes['class'] .= ' statusicons'; } @@ -967,7 +970,7 @@ public function get_right_rows(bool $displayaverages) : array { $gradepass = ''; $context->gradepassicon = ''; } - $context->statusicons = $this->set_grade_status_icons($element); + $context->statusicons = $this->gtree->set_grade_status_icons($element); // If in editing mode, we need to print either a text box or a drop down (for scales) // grades in item of type grade category or course are not directly editable. @@ -1007,9 +1010,9 @@ public function get_right_rows(bool $displayaverages) : array { if ($quickgrading && $grade->is_editable()) { $context->iseditable = true; if (empty($item->outcomeid)) { - $nogradestr = $this->get_lang_string('nograde'); + $nogradestr = \grade_helper::get_lang_string('nograde'); } else { - $nogradestr = $this->get_lang_string('nooutcome', 'grades'); + $nogradestr = \grade_helper::get_lang_string('nooutcome', 'grades'); } $attributes = [ 'tabindex' => $tabindices[$item->id]['grade'], @@ -1092,7 +1095,7 @@ public function get_right_rows(bool $displayaverages) : array { } if (!$item->needsupdate) { - $context->actionmenu = $this->get_cell_action_menu($element, 'gradeitem'); + $context->actionmenu = $this->gtree->get_cell_action_menu($element, 'gradeitem', $this->gpr); } $itemcell->text = $OUTPUT->render_from_template('gradereport_grader/cell', $context); @@ -1120,51 +1123,6 @@ public function get_right_rows(bool $displayaverages) : array { return $rows; } - /** - * Sets status icons for the grade. - * @param array $element array with grade item info - * - * @return string status icons container HTML - */ - public function set_grade_status_icons(array $element) : string { - global $OUTPUT; - - $attributes = ['class' => 'text-muted']; - - $statusicons = ''; - if ($element['object']->is_hidden()) { - $statusicons .= $OUTPUT->pix_icon('i/show', $this->get_lang_string('hidden', 'grades'), - 'moodle', $attributes); - } - - if ($element['object']->is_locked()) { - $statusicons .= $OUTPUT->pix_icon('i/lock', $this->get_lang_string('locked', 'grades'), - 'moodle', $attributes); - } - - if ($element['object'] instanceof grade_grade) { - $grade = $element['object']; - if ($grade->is_overridden()) { - $statusicons .= $OUTPUT->pix_icon('i/overriden_grade', - $this->get_lang_string('overridden', 'grades'), 'moodle', $attributes); - } - - if ($grade->is_excluded()) { - $statusicons .= $OUTPUT->pix_icon('i/excluded', $this->get_lang_string('excluded', 'grades'), - 'moodle', $attributes); - } - } - - $class = 'grade_icons'; - if ($element['type'] == 'category') { - $class = 'category_grade_icons'; - } - if ($statusicons) { - $statusicons = $OUTPUT->container($statusicons, $class); - } - return $statusicons; - } - /** * Depending on the style of report (fixedstudents vs traditional one-table), * arranges the rows of data in one or two tables, and returns the output of @@ -1218,7 +1176,7 @@ public function get_left_icons_row($rows=array(), $colspan=1) { $controlscell->attributes['class'] = 'header controls'; $controlscell->header = true; $controlscell->colspan = $colspan; - $controlscell->text = $this->get_lang_string('controls', 'grades'); + $controlscell->text = \grade_helper::get_lang_string('controls', 'grades'); $controlsrow->cells[] = $controlscell; $rows[] = $controlsrow; @@ -1243,7 +1201,7 @@ public function get_left_range_row($rows=array(), $colspan=1) { $rangecell->colspan = $colspan; $rangecell->header = true; $rangecell->scope = 'row'; - $rangecell->text = $this->get_lang_string('range', 'grades'); + $rangecell->text = \grade_helper::get_lang_string('range', 'grades'); $rangerow->cells[] = $rangecell; $rows[] = $rangerow; } @@ -1547,7 +1505,7 @@ public function get_right_avg_row($rows=array(), $grouponly=false) { * @return string HTML */ protected function get_course_header($element) { - $actionmenu = $this->get_cell_action_menu($element, 'gradeitem'); + $actionmenu = $this->gtree->get_cell_action_menu($element, 'gradeitem', $this->gpr); if (in_array($element['object']->id, $this->collapsed['aggregatesonly'])) { $showing = get_string('showingaggregatesonly', 'grades'); @@ -1628,179 +1586,6 @@ protected function get_icons($element) { return $OUTPUT->container($editicon.$editcalculationicon.$showhideicon.$lockunlockicon.$gradeanalysisicon, 'grade_icons'); } - /** - * Returns an action menu for the grade. - * - * @param array $element Array with cell info. - * @param string $mode Mode - gradeitem or user - * @return string - */ - public function get_cell_action_menu(array $element, string $mode): string { - global $OUTPUT, $USER, $CFG; - - $context = new stdClass(); - - if ($mode == 'gradeitem') { - $editable = true; - $editstrings = []; - $editstrings[] = $this->get_lang_string('editgrade', 'grades'); - $editstrings[] = $this->get_lang_string('itemsedit', 'grades'); - $editstrings[] = $this->get_lang_string('categoryedit', 'grades'); - - $editcalculationstrings = $this->get_lang_string('editcalculation', 'grades'); - - $hidestrings = []; - $hidestrings[] = $this->get_lang_string('show'); - $hidestrings[] = $this->get_lang_string('hide'); - - $lockstrings = []; - $lockstrings[] = $this->get_lang_string('unlock', 'grades'); - $lockstrings[] = $this->get_lang_string('lock', 'grades'); - - $gradeanalysisstring = $this->get_lang_string('gradeanalysis', 'grades'); - - $titleasc = $this->get_lang_string('asc'); - $titledesc = $this->get_lang_string('desc'); - - if ($element['type'] == 'grade') { - $item = $element['object']->grade_item; - if ($item->is_course_item() || $item->is_category_item()) { - $editable = $this->overridecat; - } - - if (!empty($USER->editing)) { - if ($editable) { - $context->editurl = $this->gtree->get_edit_link($element, $this->gpr, $editstrings); - } - $context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings); - $context->lockurl = $this->gtree->get_locking_link($element, $this->gpr, $lockstrings); - } - - $context->gradeanalysisurl = $this->gtree->get_grade_analysis_link($element['object'], $gradeanalysisstring); - } else if (($element['type'] == 'item') || - ($element['type'] == 'categoryitem') || - ($element['type'] == 'courseitem') || - ($element['type'] == 'userfield')) { - - $context->datatype = 'item'; - - if ($element['type'] == 'item') { - foreach ($this->get_report_links($this->context, $this->courseid, $element, $this->gpr, $mode) - as $count => $reportlink) { - $temp = 'reporturl' . $count; - $context->$temp = $reportlink; - } - $context->advancedgradingurl = $this->gtree->get_advanced_grading_link($element, $this->gpr); - } - - if ($element['type'] == 'item') { - $context->divider1 = true; - } - if (!empty($USER->editing)) { - if ($element['type'] !== 'userfield') { - $context->divider1 = true; - $context->divider2 = true; - } - if ($element['type'] == 'item') { - $context->editurl = $this->gtree->get_edit_link($element, $this->gpr, $editstrings); - } - - $context->editcalculationurl = - $this->gtree->get_edit_calculation_link($element, $this->gpr, $editcalculationstrings); - - if (isset($element['object'])) { - $object = $element['object']; - if ($object->itemmodule !== 'quiz') { - $context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings); - } - } - $context->lockurl = $this->gtree->get_locking_link($element, $this->gpr, $lockstrings); - } - - // Sorting item. - $sortlink = clone($this->baseurl); - if (isset($element['object']->id)) { - $sortlink->param('sortitemid', $element['object']->id); - } else if ($element['type'] == 'userfield') { - $context->datatype = $element['name']; - $sortlink->param('sortitemid', $element['name']); - } - - if (($element['type'] == 'userfield') && ($element['name'] == 'fullname')) { - $sortlink->param('sortitemid', 'firstname'); - $context->ascendingfirstnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc); - $context->descendingfirstnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc'); - - $sortlink->param('sortitemid', 'lastname'); - $context->ascendinglastnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc); - $context->descendinglastnameurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc'); - } else { - $context->ascendingurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titleasc); - $context->descendingurl = $this->gtree->get_sorting_link($sortlink, $this->gpr, $titledesc, 'desc'); - } - - } else if ($element['type'] == 'category') { - $context->datatype = 'category'; - - $categoryid = $element['object']->id; - - // Load language strings. - $strswitchminus = $this->get_lang_string('aggregatesonly', 'grades'); - $strswitchplus = $this->get_lang_string('gradesonly', 'grades'); - $strswitchwhole = $this->get_lang_string('fullmode', 'grades'); - - $url = new moodle_url($this->gpr->get_return_url(null, - ['target' => $element['eid'], 'sesskey' => sesskey()])); - - $gradesonly = false; - $aggregatesonly = false; - $fullmode = false; - if (in_array($categoryid, $this->collapsed['gradesonly'])) { - $gradesonly = true; - } else if (in_array($categoryid, $this->collapsed['aggregatesonly'])) { - $aggregatesonly = true; - } else { - $fullmode = true; - } - $context->gradesonlyurl = - $this->gtree->get_category_view_mode_link($url, $strswitchplus, 'switch_plus', $gradesonly); - $context->aggregatesonlyurl = - $this->gtree->get_category_view_mode_link($url, $strswitchminus, 'switch_minus', $aggregatesonly); - $context->fullmodeurl = - $this->gtree->get_category_view_mode_link($url, $strswitchwhole, 'switch_whole', $fullmode); - - if (!empty($USER->editing)) { - $context->divider1 = true; - $context->editurl = $this->gtree->get_edit_link($element, $this->gpr, $editstrings); - $context->hideurl = $this->gtree->get_hiding_link($element, $this->gpr, $hidestrings); - $context->lockurl = $this->gtree->get_locking_link($element, $this->gpr, $lockstrings); - } - - } - - if (isset($element['object'])) { - $context->dataid = $element['object']->id; - } else if ($element['type'] == 'userfield') { - $context->dataid = $element['name']; - } - } else if ($mode == 'user') { - $context->datatype = 'user'; - foreach ($this->get_report_links($this->context, $this->courseid, $element, $this->gpr, $mode) - as $count => $reportlink) { - $temp = 'reporturl' . $count; - $context->$temp = $reportlink; - } - $context->dataid = $element['userid']; - } - - if (!empty($USER->editing) || isset($context->gradeanalysisurl) || isset($context->gradesonlyurl) - || isset($context->aggregatesonlyurl) || isset($context->fullmodeurl) || isset($context->reporturl0) - || isset($context->ascendingurl) || isset($context->ascendingfirstnameurl)) { - return $OUTPUT->render_from_template('gradereport_grader/cellmenu', $context); - } - return ''; - } - /** * Given a category element returns collapsing +/- icon if available * @@ -2034,7 +1819,7 @@ public function get_sort_arrows(array $extrafields = array()) { if (!empty($requirednames)) { foreach ($requirednames as $name) { $arrows['studentname'] .= html_writer::link( - new moodle_url($this->baseurl, array('sortitemid' => $name)), $this->get_lang_string($name) + new moodle_url($this->baseurl, array('sortitemid' => $name)), \grade_helper::get_lang_string($name) ); if ($this->sortitemid == $name) { $sortlink->param('sortitemid', $name); @@ -2080,4 +1865,76 @@ public function get_students_per_page(): int { // Default to the lowest available option. return (int) get_user_preferences('grade_report_studentsperpage', min(static::PAGINATION_OPTIONS)); } + + /** + * Returns link to change category view mode. + * + * @param moodle_url $url Url to grader report page + * @param string $title Menu item title + * @param string $action View mode to change to + * @param bool $active Whether link is active in dropdown + * + * @return string|null + */ + public function get_category_view_mode_link(moodle_url $url, string $title, string $action, bool $active = false): ?string { + $urlnew = $url; + $urlnew->param('action', $action); + $active = $active ? 'true' : 'false'; + return html_writer::link($urlnew, $title, + ['class' => 'dropdown-item', 'aria-label' => $title, 'aria-current' => $active, 'role' => 'menuitem']); + } +} + +/** + * Adds report specific context variable + * + * @param context_course $context Course context + * @param int $courseid Course ID + * @param array $element An array representing an element in the grade_tree + * @param grade_plugin_return $gpr A grade_plugin_return object + * @param string $mode Not used + * @param stdClass|null $templatecontext Template context + * @return stdClass|null + */ +function gradereport_grader_get_report_link(context_course $context, int $courseid, + array $element, grade_plugin_return $gpr, string $mode, ?stdClass $templatecontext): ?stdClass { + + if ($mode == 'category') { + static $report = null; + if (!$report) { + $report = new grade_report_grader($courseid, $gpr, $context); + } + + if (!isset($templatecontext)) { + $templatecontext = new stdClass(); + } + + $categoryid = $element['object']->id; + + // Load language strings. + $strswitchminus = grade_helper::get_lang_string('aggregatesonly', 'grades'); + $strswitchplus = grade_helper::get_lang_string('gradesonly', 'grades'); + $strswitchwhole = grade_helper::get_lang_string('fullmode', 'grades'); + + $url = new moodle_url($gpr->get_return_url(null, ['target' => $element['eid'], 'sesskey' => sesskey()])); + + $gradesonly = false; + $aggregatesonly = false; + $fullmode = false; + if (in_array($categoryid, $report->collapsed['gradesonly'])) { + $gradesonly = true; + } else if (in_array($categoryid, $report->collapsed['aggregatesonly'])) { + $aggregatesonly = true; + } else { + $fullmode = true; + } + $templatecontext->gradesonlyurl = + $report->get_category_view_mode_link($url, $strswitchplus, 'switch_plus', $gradesonly); + $templatecontext->aggregatesonlyurl = + $report->get_category_view_mode_link($url, $strswitchminus, 'switch_minus', $aggregatesonly); + $templatecontext->fullmodeurl = + $report->get_category_view_mode_link($url, $strswitchwhole, 'switch_whole', $fullmode); + return $templatecontext; + } + return null; } diff --git a/grade/report/grader/tests/behat/behat_gradereport_grader.php b/grade/report/grader/tests/behat/behat_gradereport_grader.php index 4f2c4fd10074f..08883c5d1b979 100644 --- a/grade/report/grader/tests/behat/behat_gradereport_grader.php +++ b/grade/report/grader/tests/behat/behat_gradereport_grader.php @@ -58,6 +58,8 @@ protected function get_user_id($name) { /** * Gets the grade item id from its name. * + * @deprecated since 4.2 + * @todo MDL-77107 This will be deleted in Moodle 4.6. * @throws Exception * @param string $itemname * @return int @@ -66,6 +68,9 @@ protected function get_grade_item_id($itemname) { global $DB; + debugging('behat_gradereport_grader::get_grade_item_id() is deprecated, please use' . + ' behat_grades::get_grade_item_id() instead.', DEBUG_DEVELOPER); + if ($id = $DB->get_field('grade_items', 'id', array('itemname' => $itemname))) { return $id; } diff --git a/grade/report/lib.php b/grade/report/lib.php index 9cd9c226e7ef1..aaaca6e056d96 100644 --- a/grade/report/lib.php +++ b/grade/report/lib.php @@ -92,12 +92,6 @@ abstract class grade_report { */ public $page; - /** - * Array of cached language strings (using get_string() all the time takes a long time!). - * @var array $lang_strings - */ - public $lang_strings = array(); - // GROUP VARIABLES (including SQL) /** @@ -307,37 +301,51 @@ abstract public function process_data($data); abstract public function process_action($target, $action); /** - * Returns an array of links to appropriate report pages for the current element + * Add additional links specific to plugin * @param context_course $context Course context * @param int $courseid Course ID * @param array $element An array representing an element in the grade_tree * @param grade_plugin_return $gpr A grade_plugin_return object - * @param string $mode Mode - gradeitem or user - * @return array Link to appropriate report - */ - public function get_report_links(context_course $context, int $courseid, array $element, - grade_plugin_return $gpr, string $mode): array { - - $reports = []; - foreach (core_component::get_plugin_list('gradereport') as $plugin => $plugindir) { - $params = [$context, $courseid, $element, $gpr, $mode]; - $component = 'gradereport_' . $plugin; - if ($reportlink = component_callback($component, 'get_report_link', $params)) { - $reports[] = $reportlink; + * @param string $mode Mode (user or grade item) + * @param stdClass $templatecontext Template context + * @param bool $otherplugins If we need to insert links to other plugins + * @return ?stdClass Updated template context + */ + public static function get_additional_context(context_course $context, int $courseid, array $element, + grade_plugin_return $gpr, string $mode, stdClass $templatecontext, bool $otherplugins = false): ?stdClass { + + if (!$otherplugins) { + $component = 'gradereport_' . $gpr->plugin; + $params = [$context, $courseid, $element, $gpr, $mode, $templatecontext]; + return component_callback($component, 'get_report_link', $params); + } else { + // Loop through all installed grade reports. + foreach (core_component::get_plugin_list('gradereport') as $plugin => $plugindir) { + $params = [$context, $courseid, $element, $gpr, $mode, $templatecontext]; + $component = 'gradereport_' . $plugin; + $templatecontextupdated = component_callback($component, 'get_report_link', $params); + if ($templatecontextupdated) { + $templatecontext = $templatecontextupdated; + } } - + return $templatecontext; } - return $reports; } /** * First checks the cached language strings, then returns match if found, or uses get_string() * to get it from the DB, caches it then returns it. + * + * @deprecated since 4.2 + * @todo MDL-77307 This will be deleted in Moodle 4.6. * @param string $strcode * @param string $section Optional language section * @return string */ public function get_lang_string($strcode, $section=null) { + debugging('grade_report::get_lang_string() is deprecated, please use' . + ' grade_helper::get_lang_string() instead.', DEBUG_DEVELOPER); + if (empty($this->lang_strings[$strcode])) { $this->lang_strings[$strcode] = get_string($strcode, $section); } @@ -588,7 +596,7 @@ protected function get_sort_arrow(string $direction = 'down', ?moodle_url $sortl global $OUTPUT; $pix = ['up' => 't/sort_desc', 'down' => 't/sort_asc']; $matrix = ['up' => 'desc', 'down' => 'asc']; - $strsort = $this->get_lang_string($matrix[$direction], 'moodle'); + $strsort = grade_helper::get_lang_string($matrix[$direction], 'moodle'); $arrow = $OUTPUT->pix_icon($pix[$direction], '', '', ['class' => 'sorticon']); return html_writer::link($sortlink, $arrow, ['title' => $strsort, 'aria-label' => $strsort]); } diff --git a/grade/report/overview/lib.php b/grade/report/overview/lib.php index 16479289fe79c..1398e1b815d74 100644 --- a/grade/report/overview/lib.php +++ b/grade/report/overview/lib.php @@ -151,13 +151,13 @@ public function setup_table() { // setting up table headers if ($this->showrank['any']) { $tablecolumns = array('coursename', 'grade', 'rank'); - $tableheaders = array($this->get_lang_string('coursename', 'grades'), - $this->get_lang_string('gradenoun'), - $this->get_lang_string('rank', 'grades')); + $tableheaders = array(grade_helper::get_lang_string('coursename', 'grades'), + grade_helper::get_lang_string('gradenoun'), + grade_helper::get_lang_string('rank', 'grades')); } else { $tablecolumns = array('coursename', 'grade'); - $tableheaders = array($this->get_lang_string('coursename', 'grades'), - $this->get_lang_string('gradenoun')); + $tableheaders = array(grade_helper::get_lang_string('coursename', 'grades'), + grade_helper::get_lang_string('gradenoun')); } $this->table = new flexible_table('grade-report-overview-'.$this->user->id); diff --git a/grade/report/singleview/lib.php b/grade/report/singleview/lib.php index 24ddb8ac3bb8d..e9e7a89624b07 100644 --- a/grade/report/singleview/lib.php +++ b/grade/report/singleview/lib.php @@ -30,12 +30,16 @@ * @param array $element An array representing an element in the grade_tree * @param grade_plugin_return $gpr A grade_plugin_return object * @param string $mode Mode - gradeitem or user - * @return string|null + * @param ?stdClass $templatecontext Template context + * @return stdClass|null */ function gradereport_singleview_get_report_link(context_course $context, int $courseid, - array $element, grade_plugin_return $gpr, string $mode): ?string { + array $element, grade_plugin_return $gpr, string $mode, ?stdClass $templatecontext): ?stdClass { $reportstring = grade_helper::get_lang_string('singleviewreport_' . $mode, 'gradereport_singleview'); + if (!isset($templatecontext)) { + $templatecontext = new stdClass(); + } if ($mode == 'gradeitem') { // View all grades items. @@ -50,8 +54,9 @@ function gradereport_singleview_get_report_link(context_course $context, int $co 'itemid' => $element['object']->id ]); $gpr->add_url_params($url); - return html_writer::link($url, $reportstring, + $templatecontext->reporturl0 = html_writer::link($url, $reportstring, ['class' => 'dropdown-item', 'aria-label' => $reportstring, 'role' => 'menuitem']); + return $templatecontext; } } } else if ($mode == 'user') { @@ -66,8 +71,9 @@ function gradereport_singleview_get_report_link(context_course $context, int $co $url = new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid, 'itemid' => $element['userid'], 'item' => 'user']); $gpr->add_url_params($url); - return html_writer::link($url, $reportstring, + $templatecontext->reporturl0 = html_writer::link($url, $reportstring, ['class' => 'dropdown-item', 'aria-label' => $reportstring, 'role' => 'menuitem']); + return $templatecontext; } } return null; diff --git a/grade/report/upgrade.txt b/grade/report/upgrade.txt index 0ddb564216fa1..9d11a16f32dca 100644 --- a/grade/report/upgrade.txt +++ b/grade/report/upgrade.txt @@ -11,12 +11,15 @@ information provided here is intended especially for developers. * 'Show show/hide icons' setting has been removed from grader report (link is moved to grade action menu) * 'Enable AJAX' interface has been deprecated for grader report * 'Quick feedback' interface has been deprecated for grader report -* A new method grade_report::get_report_links() is created to obtain links to other grade plugins report pages. +* A new method grade_report::get_additional_context() is created to obtain links to other grade plugins report pages. It loops through all installed grade report plugins and checks if callback function gradereport_*_get_report_link is implemented in for given grade report plugin in the corresponding lib.php * The setting $CFG->grade_report_studentsperpage has been completely removed because it's not required anymore. This setting was used to set the default number of students displayed per page in the grader report. Now the default is set to 20. +* The get_grade_item_id() function in behat_gradereport_grader.php has been deprecated. Please use + behat_grades::get_grade_item_id() instead. +* The grade_report::get_lang_string() has been deprecated. Please use grade_helper::get_lang_string() instead. === 3.6 === * External function gradereport_user_external::get_grade_items now return the following information (only for course managers). diff --git a/grade/report/user/classes/report/user.php b/grade/report/user/classes/report/user.php index 4820acd72fc49..b020668d6eacd 100644 --- a/grade/report/user/classes/report/user.php +++ b/grade/report/user/classes/report/user.php @@ -27,7 +27,9 @@ defined('MOODLE_INTERNAL') || die; +global $CFG; require_once($CFG->dirroot.'/grade/report/lib.php'); +require_once($CFG->dirroot.'/grade/lib.php'); /** * Class providing an API for the user report building and displaying. @@ -373,51 +375,51 @@ public function setup_table() { // Setting up table headers. $this->tablecolumns = ['itemname']; - $this->tableheaders = [$this->get_lang_string('gradeitem', 'grades')]; + $this->tableheaders = [\grade_helper::get_lang_string('gradeitem', 'grades')]; if ($this->showweight) { $this->tablecolumns[] = 'weight'; - $this->tableheaders[] = $this->get_lang_string('weightuc', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('weightuc', 'grades'); } if ($this->showgrade) { $this->tablecolumns[] = 'grade'; - $this->tableheaders[] = $this->get_lang_string('grade', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('grade', 'grades'); } if ($this->showrange) { $this->tablecolumns[] = 'range'; - $this->tableheaders[] = $this->get_lang_string('range', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('range', 'grades'); } if ($this->showpercentage) { $this->tablecolumns[] = 'percentage'; - $this->tableheaders[] = $this->get_lang_string('percentage', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('percentage', 'grades'); } if ($this->showlettergrade) { $this->tablecolumns[] = 'lettergrade'; - $this->tableheaders[] = $this->get_lang_string('lettergrade', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('lettergrade', 'grades'); } if ($this->showrank) { $this->tablecolumns[] = 'rank'; - $this->tableheaders[] = $this->get_lang_string('rank', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('rank', 'grades'); } if ($this->showaverage) { $this->tablecolumns[] = 'average'; - $this->tableheaders[] = $this->get_lang_string('average', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('average', 'grades'); } if ($this->showfeedback) { $this->tablecolumns[] = 'feedback'; - $this->tableheaders[] = $this->get_lang_string('feedback', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('feedback', 'grades'); } if ($this->showcontributiontocoursetotal) { $this->tablecolumns[] = 'contributiontocoursetotal'; - $this->tableheaders[] = $this->get_lang_string('contributiontocoursetotal', 'grades'); + $this->tableheaders[] = \grade_helper::get_lang_string('contributiontocoursetotal', 'grades'); } } @@ -1008,7 +1010,7 @@ public function print_table(bool $return = false) { $table = new \html_table(); $table->attributes = [ - 'summary' => s($this->get_lang_string('tablesummary', 'gradereport_user')), + 'summary' => s(\grade_helper::get_lang_string('tablesummary', 'gradereport_user')), 'class' => 'generaltable boxaligncenter user-grade', ]; diff --git a/grade/report/user/lib.php b/grade/report/user/lib.php index 54c384505d3e2..252cb625ec223 100644 --- a/grade/report/user/lib.php +++ b/grade/report/user/lib.php @@ -247,15 +247,20 @@ function gradereport_user_myprofile_navigation(tree $tree, stdClass $user, bool * @param array $element An array representing an element in the grade_tree * @param grade_plugin_return $gpr A grade_plugin_return object * @param string $mode Mode - gradeitem or user - * @return string|null + * @param ?stdClass $templatecontext Template context + * @return stdClass|null */ function gradereport_user_get_report_link(context_course $context, int $courseid, array $element, - grade_plugin_return $gpr, string $mode): ?string { + grade_plugin_return $gpr, string $mode, ?stdClass $templatecontext): ?stdClass { global $CFG; if ($mode == 'user') { $reportstring = grade_helper::get_lang_string('userreport_' . $mode, 'gradereport_user'); + if (!isset($templatecontext)) { + $templatecontext = new stdClass(); + } + // FIXME: MDL-52678 This get_capability_info is hacky and we should have an API for inserting grade row links instead. $canseeuserreport = false; if (get_capability_info('gradereport/' . $CFG->grade_profilereport . ':view')) { @@ -266,8 +271,9 @@ function gradereport_user_get_report_link(context_course $context, int $courseid $url = new moodle_url('/grade/report/' . $CFG->grade_profilereport . '/index.php', ['userid' => $element['userid'], 'id' => $courseid]); $gpr->add_url_params($url); - return html_writer::link($url, $reportstring, + $templatecontext->reporturl1 = html_writer::link($url, $reportstring, ['class' => 'dropdown-item', 'aria-label' => $reportstring, 'role' => 'menuitem']); + return $templatecontext; } } return null; diff --git a/grade/report/grader/templates/cellmenu.mustache b/grade/templates/cellmenu.mustache similarity index 98% rename from grade/report/grader/templates/cellmenu.mustache rename to grade/templates/cellmenu.mustache index f3f73a8c4c720..84129ff1eeea0 100644 --- a/grade/report/grader/templates/cellmenu.mustache +++ b/grade/templates/cellmenu.mustache @@ -15,7 +15,7 @@ along with Moodle. If not, see . }} {{! - @template gradereport_grader/cellmenu + @template core_grades/cellmenu This template renders action menu for a given cell. Example context (json): @@ -31,8 +31,8 @@ "ascendinglastnameurl": "Ascending", "descendinglastnameurl": "Descending", "divider1": "true", - "divider2": "true" - "datatype": item, + "divider2": "true", + "datatype": "item", "dataid": "123" } }}