diff --git a/grade/lib.php b/grade/lib.php index 4c7e3f90c22..54fcfe54319 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -1722,15 +1722,15 @@ class grade_structure { * 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 @@ class grade_structure { * * @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 @@ class grade_structure { ['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 @@ class grade_structure { ['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 @@ class grade_structure { * * @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 @@ class grade_structure { 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 @@ class grade_structure { * * @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 @@ class grade_structure { $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 @@ class grade_structure { * * @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 @@ class grade_structure { // 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 - * - * @return string|null + * @param array $element array with grade item info + * @return string status icons container HTML */ - 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 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. + * + * @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_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 @@ class grade_structure { * * @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 ba1e18b07b8..25e01cbcebe 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -658,7 +658,8 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { // 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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { ' 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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { 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 @@ class grade_report_grader extends grade_report { } 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 @@ class grade_report_grader extends grade_report { 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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { $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 @@ class grade_report_grader extends grade_report { * @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 @@ class grade_report_grader extends grade_report { 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 @@ class grade_report_grader extends grade_report { 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 @@ class grade_report_grader extends grade_report { // 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 4f2c4fd1007..08883c5d1b9 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 @@ class behat_gradereport_grader extends behat_base { /** * 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 @@ class behat_gradereport_grader extends behat_base { 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 9cd9c226e7e..aaaca6e056d 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 class grade_report { 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 + * @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 function get_report_links(context_course $context, int $courseid, array $element, - grade_plugin_return $gpr, string $mode): array { + 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 { - $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; + 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 @@ abstract class grade_report { 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 16479289fe7..1398e1b815d 100644 --- a/grade/report/overview/lib.php +++ b/grade/report/overview/lib.php @@ -151,13 +151,13 @@ class grade_report_overview extends grade_report { // 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 24ddb8ac3bb..e9e7a89624b 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 0ddb564216f..9d11a16f32d 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 4820acd72fc..b020668d6ea 100644 --- a/grade/report/user/classes/report/user.php +++ b/grade/report/user/classes/report/user.php @@ -27,7 +27,9 @@ use moodle_url; 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 @@ class user extends grade_report { // 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 @@ class user extends grade_report { $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 54c384505d3..252cb625ec2 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 f3f73a8c4c7..84129ff1eee 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" } }}