diff --git a/.upgradenotes/MDL-80752-2024061412574424.yml b/.upgradenotes/MDL-80752-2024061412574424.yml new file mode 100644 index 00000000000..a1bee18856a --- /dev/null +++ b/.upgradenotes/MDL-80752-2024061412574424.yml @@ -0,0 +1,8 @@ +issueNumber: MDL-80752 +notes: + mod_assign: + - message: > + The `$submissionpluginenabled` and `$submissioncount` parameters from + the constructor of the `mod_assign\output::grading_actionmenu` class + have been deprecated. + type: deprecated diff --git a/lib/tests/behat/alpha_chooser.feature b/lib/tests/behat/alpha_chooser.feature index 448fbe162c3..2bba3feb388 100644 --- a/lib/tests/behat/alpha_chooser.feature +++ b/lib/tests/behat/alpha_chooser.feature @@ -126,7 +126,7 @@ Feature: Initials bar | assign | C1 | assign1 | TestAssignment | Test assignment description | 0 | 0 | And I am on the "assign1" "Activity" page logged in as "teacher" When I follow "View all submissions" - And I select "View gradebook" from the "jump" singleselect + And I choose the "View gradebook" item in the "Actions" action menu And I click on "Filter by name" "combobox" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.lastinitial" "css_element" @@ -157,7 +157,7 @@ Feature: Initials bar And I should not see "Cstudent Cstudent" And I am on the "assign1" "Activity" page When I follow "View all submissions" - And I select "View gradebook" from the "jump" singleselect + And I choose the "View gradebook" item in the "Actions" action menu And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should exist in the ".initialbar.firstinitial" "css_element" diff --git a/mod/assign/classes/output/grading_actionmenu.php b/mod/assign/classes/output/grading_actionmenu.php index 2febf1a5d0d..9687a734737 100644 --- a/mod/assign/classes/output/grading_actionmenu.php +++ b/mod/assign/classes/output/grading_actionmenu.php @@ -40,25 +40,34 @@ use moodle_url; class grading_actionmenu implements templatable, renderable { /** @var int Course module ID. */ - protected $cmid; + protected int $cmid; /** @var bool If any submission plugins are enabled. */ - protected $submissionpluginenabled; + protected bool $submissionpluginenabled; /** @var int The number of submissions made. */ - protected $submissioncount; - + protected int $submissioncount; + /** @var assign The assign instance. */ + protected assign $assign; /** * Constructor for this object. * * @param int $cmid Course module ID. - * @param bool $submissionpluginenabled If any submission plugins are enabled. - * @param int $submissioncount The number of submissions made. + * @param null|bool $submissionpluginenabled This parameter has been deprecated since 4.5 and should not be used anymore. + * @param null|int $submissioncount This parameter has been deprecated since 4.5 and should not be used anymore. + * @param assign|null $assign The assign instance. If not provided, it will be loaded based on the cmid. */ - public function __construct(int $cmid, bool $submissionpluginenabled = false, int $submissioncount = 0) { + public function __construct( + int $cmid, + ?bool $submissionpluginenabled = null, + ?int $submissioncount = null, + assign $assign = null + ) { $this->cmid = $cmid; - $this->submissionpluginenabled = $submissionpluginenabled; - $this->submissioncount = $submissioncount; - + if (!$assign) { + $context = context_module::instance($cmid); + $assign = new assign($context, null, null); + } + $this->assign = $assign; } /** @@ -70,25 +79,15 @@ class grading_actionmenu implements templatable, renderable { public function export_for_template(\renderer_base $output): array { global $PAGE; - $course = $PAGE->course; + $course = $this->assign->get_course(); + $actionbarrenderer = $PAGE->get_renderer('core_course', 'actionbar'); $data = []; - $context = context_module::instance($this->cmid); - $assign = new assign($context, null, null); - $assignid = $assign->get_instance()->id; - - if ($this->submissionpluginenabled && $this->submissioncount) { - $data['downloadall'] = ( - new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'downloadall']) - )->out(false); - } - $userid = optional_param('userid', null, PARAM_INT); // If the user ID is set, it indicates that a user has been selected. In this case, override the user search // string with the full name of the selected user. $usersearch = $userid ? fullname(\core_user::get_user($userid)) : optional_param('search', '', PARAM_NOTAGS); - $actionbarrenderer = $PAGE->get_renderer('core_course', 'actionbar'); $resetlink = new moodle_url('/mod/assign/view.php', ['id' => $this->cmid, 'action' => 'grading']); $groupid = groups_get_course_group($course, true); $userselector = new \core_course\output\actionbar\user_selector( @@ -97,7 +96,7 @@ class grading_actionmenu implements templatable, renderable { userid: $userid, groupid: $groupid, usersearch: $usersearch, - instanceid: $assignid + instanceid: $this->assign->get_instance()->id ); $data['userselector'] = $actionbarrenderer->render($userselector); @@ -114,6 +113,71 @@ class grading_actionmenu implements templatable, renderable { $data['pagereset'] = $reset->out(false); } + $actions = $this->get_actions(); + if ($actions) { + $menu = new \action_menu(); + $menu->set_menu_trigger(get_string('actions'), 'btn btn-outline-primary'); + foreach ($actions as $groupkey => $actiongroup) { + foreach ($actiongroup as $label => $url) { + $menu->add(new \action_menu_link_secondary(new \moodle_url($url), null, $label)); + } + if ($groupkey !== array_key_last($actions)) { + $divider = new \action_menu_filler(); + $divider->primary = false; + $menu->add($divider); + } + } + + $renderer = $PAGE->get_renderer('core'); + $data['actions'] = $renderer->render($menu); + } + return $data; } + + /** + * Get the actions for the grading action menu. + * + * @return array A 2D array of actions grouped by a key in the form of key => label => URL. + */ + private function get_actions() { + $actions = []; + if ( + has_capability('gradereport/grader:view', $this->assign->get_course_context()) + && has_capability('moodle/grade:viewall', $this->assign->get_course_context()) + ) { + $url = new moodle_url('/grade/report/grader/index.php', ['id' => $this->assign->get_course()->id]); + $actions['gradebook'][get_string('viewgradebook', 'assign')] = $url->out(false); + } + if ($this->assign->is_blind_marking() && has_capability('mod/assign:revealidentities', $this->assign->get_context())) { + $url = new moodle_url('/mod/assign/view.php', [ + 'id' => $this->assign->get_course_module()->id, + 'action' => 'revealidentities', + ]); + $actions['blindmarking'][get_string('revealidentities', 'assign')] = $url->out(false); + } + foreach ($this->assign->get_feedback_plugins() as $plugin) { + if ($plugin->is_enabled() && $plugin->is_visible()) { + foreach ($plugin->get_grading_actions() as $action => $description) { + $url = new moodle_url('/mod/assign/view.php', [ + 'id' => $this->assign->get_course_module()->id, + 'plugin' => $plugin->get_type(), + 'pluginsubtype' => 'assignfeedback', + 'action' => 'viewpluginpage', + 'pluginaction' => $action, + ]); + $actions['assignfeedback_' . $plugin->get_type()][$description] = $url->out(false); + } + } + } + if ($this->assign->is_any_submission_plugin_enabled() && $this->assign->count_submissions()) { + $url = new moodle_url('/mod/assign/view.php', [ + 'id' => $this->assign->get_course_module()->id, + 'action' => 'downloadall', + ]); + $actions['downloadall'][get_string('downloadall', 'mod_assign')] = $url->out(false); + } + + return $actions; + } } diff --git a/mod/assign/feedback/file/lang/en/assignfeedback_file.php b/mod/assign/feedback/file/lang/en/assignfeedback_file.php index d9bfd017057..c47d7a51025 100644 --- a/mod/assign/feedback/file/lang/en/assignfeedback_file.php +++ b/mod/assign/feedback/file/lang/en/assignfeedback_file.php @@ -49,7 +49,7 @@ $string['moreusers'] = '{$a} more...'; $string['nochanges'] = 'No changes'; $string['pluginname'] = 'File feedback'; $string['uploadfiles'] = 'Send feedback files'; -$string['uploadzip'] = 'Upload multiple feedback files in a zip'; +$string['uploadzip'] = 'Upload feedback files in a zip'; $string['uploadzipsummary'] = 'Feedback files imported from a zip'; $string['userswithnewfeedback'] = 'Users with updated feedback: {$a}'; $string['selectedusers'] = 'Selected users'; diff --git a/mod/assign/lang/en/assign.php b/mod/assign/lang/en/assign.php index 1263a7df400..cba923a852f 100644 --- a/mod/assign/lang/en/assign.php +++ b/mod/assign/lang/en/assign.php @@ -126,7 +126,7 @@ $string['batchsetallocatedmarker'] = 'Set allocated marker for {$a} selected use $string['batchsetmarkingworkflowstateforusers'] = 'Set marking workflow state for {$a} selected user(s).'; $string['beginassignment'] = 'Begin assignment'; $string['blindmarking'] = 'Anonymous submissions'; -$string['blindmarkingenabledwarning'] = 'Anonymous submissions are enabled for this activity. Grades will not be added to the gradebook until student identities are revealed via the grading action menu.'; +$string['blindmarkingenabledwarning'] = 'Anonymous submissions are enabled for this activity. Grades will not be added to the gradebook until student identities are revealed via the "Actions" menu.'; $string['blindmarking_help'] = 'Anonymous submissions hide the identity of students from markers. Anonymous submission settings will be locked once a submission or grade has been made in relation to this assignment.'; $string['cachedef_overrides'] = 'User and group override information'; $string['calendardue'] = '{$a} is due'; @@ -135,7 +135,6 @@ $string['calendargradingdue'] = '{$a} is due to be graded'; $string['caneditsubmission'] = 'You can edit your submission and submit it after the time limit has expired, but it will be marked as late.'; $string['changeuser'] = 'Change user'; $string['changefilters'] = 'Change filters'; -$string['choosegradingaction'] = 'Grading action'; $string['choosemarker'] = 'Choose...'; $string['chooseoperation'] = 'Choose operation'; $string['clickexpandreviewpanel'] = 'Click to expand review panel'; @@ -682,5 +681,6 @@ $string['xofy'] = '{$a->x} of {$a->y}'; // Deprecated since Moodle 4.5. $string['attemptreopenmethod_none'] = 'Never'; +$string['choosegradingaction'] = 'Grading action'; $string['groupoverridesdeleted'] = 'Group overrides deleted'; $string['useroverridesdeleted'] = 'User overrides deleted'; diff --git a/mod/assign/lang/en/deprecated.txt b/mod/assign/lang/en/deprecated.txt index c0d7f84513c..66a4ab525d0 100644 --- a/mod/assign/lang/en/deprecated.txt +++ b/mod/assign/lang/en/deprecated.txt @@ -1,3 +1,4 @@ attemptreopenmethod_none,mod_assign groupoverridesdeleted,mod_assign useroverridesdeleted,mod_assign +choosegradingaction,mod_assign diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index 8de2f9c0a96..760cf577e73 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -4487,37 +4487,6 @@ class assign { $o = ''; $cmid = $this->get_course_module()->id; - $links = array(); - if (has_capability('gradereport/grader:view', $this->get_course_context()) && - has_capability('moodle/grade:viewall', $this->get_course_context())) { - $gradebookurl = '/grade/report/grader/index.php?id=' . $this->get_course()->id; - $links[$gradebookurl] = get_string('viewgradebook', 'assign'); - } - if ($this->is_blind_marking() && - has_capability('mod/assign:revealidentities', $this->get_context())) { - $revealidentitiesurl = '/mod/assign/view.php?id=' . $cmid . '&action=revealidentities'; - $links[$revealidentitiesurl] = get_string('revealidentities', 'assign'); - } - foreach ($this->get_feedback_plugins() as $plugin) { - if ($plugin->is_enabled() && $plugin->is_visible()) { - foreach ($plugin->get_grading_actions() as $action => $description) { - $url = '/mod/assign/view.php' . - '?id=' . $cmid . - '&plugin=' . $plugin->get_type() . - '&pluginsubtype=assignfeedback' . - '&action=viewpluginpage&pluginaction=' . $action; - $links[$url] = $description; - } - } - } - - // Sort links alphabetically based on the link description. - core_collator::asort($links); - - $gradingactions = new url_select($links); - $gradingactions->set_label(get_string('choosegradingaction', 'assign')); - $gradingactions->class .= ' mb-1'; - $gradingmanager = get_grading_manager($this->get_context(), 'mod_assign', 'submissions'); $perpage = $this->get_assign_perpage(); @@ -4598,8 +4567,7 @@ class assign { $gradingoptionsdata->workflowfilter = $workflowfilter; $gradingoptionsform->set_data($gradingoptionsdata); - $buttons = new \mod_assign\output\grading_actionmenu($this->get_course_module()->id, - $this->is_any_submission_plugin_enabled(), $this->count_submissions()); + $buttons = new \mod_assign\output\grading_actionmenu(cmid: $this->get_course_module()->id, assign: $this); $actionformtext = $this->get_renderer()->render($buttons); $currenturl = new moodle_url('/mod/assign/view.php', ['id' => $this->get_course_module()->id, 'action' => 'grading']); $PAGE->activityheader->set_attrs(['hidecompletion' => true]); @@ -4623,8 +4591,6 @@ class assign { $o .= $actionformtext; - $o .= $this->get_renderer()->render($gradingactions); - // Plagiarism update status apearring in the grading book. if (!empty($CFG->enableplagiarism)) { require_once($CFG->libdir . '/plagiarismlib.php'); diff --git a/mod/assign/templates/grading_actionmenu.mustache b/mod/assign/templates/grading_actionmenu.mustache index f913173d0e9..aa45526f092 100644 --- a/mod/assign/templates/grading_actionmenu.mustache +++ b/mod/assign/templates/grading_actionmenu.mustache @@ -25,17 +25,18 @@ Context variables required for this template: * userselector - HTML that outputs the user selector * groupselector - (optional) HTML that outputs the group selector + * actions - (optional) HTML that outputs the bulk action menu Example context (json): { "userselector": "", "groupselector": "
", "pagereset": "http://moodle.local/mod/assign/view.php?id=2&action=grading&group=0", - "downloadall": "https://moodle.org" + "actions": "
" } }} -
+
{{/pagereset}} - {{#downloadall}} - - {{/downloadall}}
+
+{{#actions}} +
{{{actions}}}
+{{/actions}} +
diff --git a/mod/assign/tests/behat/assign_course_reset.feature b/mod/assign/tests/behat/assign_course_reset.feature index 84a8333b9ba..62541d0f960 100644 --- a/mod/assign/tests/behat/assign_course_reset.feature +++ b/mod/assign/tests/behat/assign_course_reset.feature @@ -115,7 +115,7 @@ Feature: Assign reset And I press "Save" When I am on the "Test assignment name" Activity page And I follow "View all submissions" - And I select "Reveal student identities" from the "Grading action" singleselect + And I choose the "Reveal student identities" item in the "Actions" action menu And I press "Continue" And I should see "Sam1 Student1" When I am on the "Course 1" "reset" page diff --git a/mod/assign/tests/behat/bulk_release_anon_submissions.feature b/mod/assign/tests/behat/bulk_release_anon_submissions.feature index 9a26885c1ce..2126991b00d 100644 --- a/mod/assign/tests/behat/bulk_release_anon_submissions.feature +++ b/mod/assign/tests/behat/bulk_release_anon_submissions.feature @@ -84,7 +84,7 @@ Feature: Bulk released grades should not be sent to gradebook while submissions And I should not see "Great job!" And I am on the "Test assignment name" "assign activity" page logged in as "teacher1" And I follow "View all submissions" - And I set the field "Grading action" to "Reveal student identities" + And I choose the "Reveal student identities" item in the "Actions" action menu And I press "Continue" Then I should see "Released" in the "Student 1" "table_row" And I should see "Released" in the "Student 2" "table_row" @@ -97,7 +97,7 @@ Feature: Bulk released grades should not be sent to gradebook while submissions @javascript @_alert Scenario: Grades are released in bulk after student identities are revealed. - When I set the field "Grading action" to "Reveal student identities" + When I choose the "Reveal student identities" item in the "Actions" action menu And I press "Continue" When I set the field "selectall" to "1" And I set the field "operation" to "Set marking workflow state" diff --git a/mod/assign/tests/behat/steps_blind_marking.feature b/mod/assign/tests/behat/steps_blind_marking.feature index cd00a7c2341..e815d9e70d9 100644 --- a/mod/assign/tests/behat/steps_blind_marking.feature +++ b/mod/assign/tests/behat/steps_blind_marking.feature @@ -58,7 +58,7 @@ Feature: Assignments correctly add feedback to the grade report when workflow an And I press "Save changes" And I follow "View all submissions" And I should see "Released" in the "I'm the student's first submission" "table_row" - And I set the field "Grading action" to "Reveal student identities" + And I choose the "Reveal student identities" item in the "Actions" action menu And I press "Continue" And I am on the "Course 1" "grades > User report > View" page logged in as "student1" Then I should see "50" @@ -72,7 +72,7 @@ Feature: Assignments correctly add feedback to the grade report when workflow an And I press "Save changes" And I follow "View all submissions" And I should see "Ready for release" in the "I'm the student's first submission" "table_row" - And I set the field "Grading action" to "Reveal student identities" + And I choose the "Reveal student identities" item in the "Actions" action menu And I press "Continue" And I change window size to "large" And I click on "Grade" "link" in the "Student 1" "table_row"