Merge branch 'MDL-72873-master-v1' of https://github.com/mihailges/moodle

This commit is contained in:
Ilya Tregubov
2021-12-16 10:21:48 +02:00
86 changed files with 2834 additions and 393 deletions
-5
View File
@@ -56,11 +56,6 @@ if (has_capability('moodle/grade:manage', $systemcontext)
'3' => '3',
'4' => '4',
'5' => '5')));
$temp->add(new admin_setting_configselect('grade_navmethod', new lang_string('navmethod', 'grades'), null,
GRADE_NAVMETHOD_TABS,
array(GRADE_NAVMETHOD_DROPDOWN => new lang_string('dropdown', 'grades'),
GRADE_NAVMETHOD_TABS => new lang_string('tabs', 'grades'),
GRADE_NAVMETHOD_COMBO => new lang_string('combo', 'grades'))));
$setting = new admin_setting_configtext('grade_export_userprofilefields',
new lang_string('gradeexportuserprofilefields', 'grades'),
@@ -385,7 +385,7 @@ Feature: Set up contextual data for tests
And I navigate to "Outcomes" in current page administration
Then I should see "Grade outcome 1" in the "#addoutcomes" "css_element"
And I should see "Grade outcome 2" in the "#removeoutcomes" "css_element"
And I follow "Edit outcomes"
And I press "Manage outcomes"
And the following should exist in the "generaltable" table:
| Full name | Short name | Scale |
| Grade outcome 2 | OT2 | Test Scale 1 |
@@ -156,7 +156,7 @@ Feature: Allow to mark course as completed without cron for activity completion
Scenario: Course completion should not be updated when teacher imports grades with csv file
Given I log in as "teacher1"
And I am on "Completion course" course homepage
And I navigate to "Import" in the course gradebook
And I navigate to "CSV file" import page in the course gradebook
And I upload "lib/tests/fixtures/upload_grades.csv" file to "File" filemanager
And I press "Upload grades"
And I set the field "Map to" to "Email address"
+49
View File
@@ -0,0 +1,49 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use templatable;
use renderable;
/**
* The base class for the action bar in the gradebook pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class action_bar implements templatable, renderable {
/** @var \context $context The context object. */
protected $context;
/**
* The class constructor.
*
* @param \context $context The context object.
*/
public function __construct(\context $context) {
$this->context = $context;
}
/**
* Returns the template for the actions bar.
*
* @return string
*/
abstract public function get_template(): string;
}
@@ -0,0 +1,65 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook course outcomes page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_outcomes_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/course_outcomes_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context,
new moodle_url('/grade/edit/outcome/course.php', ['id' => $courseid]), 'outcome', 'course');
$data = $generalnavselector->export_for_template($output);
if (has_capability('moodle/grade:manageoutcomes', $this->context)) {
// Add a button to the action bar with a link to the 'manage outcomes' page.
$manageoutcomeslink = new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]);
$manageoutcomesbutton = new \single_button($manageoutcomeslink, get_string('manageoutcomes', 'grades'),
'get', true);
$data['manageoutcomesbutton'] = $manageoutcomesbutton->export_for_template($output);
}
return $data;
}
}
+100
View File
@@ -0,0 +1,100 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook export pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class export_action_bar extends action_bar {
/** @var moodle_url $exportactiveurl The URL that should be set as active in the exports URL selector element. */
protected $exportactiveurl;
/** @var string $activeplugin The plugin of the current export grades page (xml, ods, ...). */
protected $activeplugin;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param moodle_url $exportactiveurl The URL that should be set as active in the exports URL selector element.
* @param string $activeplugin The plugin of the current export grades page (xml, ods, ...).
*/
public function __construct(\context $context, moodle_url $exportactiveurl, string $activeplugin) {
parent::__construct($context);
$this->exportactiveurl = $exportactiveurl;
$this->activeplugin = $activeplugin;
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/export_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context,
new moodle_url('/grade/export/index.php', ['id' => $courseid]), 'export', $this->activeplugin);
$data = $generalnavselector->export_for_template($output);
// Get all grades export plugins. If there isn't any available export plugins there is no need to create and
// display the exports navigation selector menu. Therefore, return only the current data.
if (!$exports = \grade_helper::get_plugins_export($courseid)) {
return $data;
}
// If exports key management is enabled, always display this item at the end of the list.
if (array_key_exists('keymanager', $exports)) {
$keymanager = $exports['keymanager'];
unset($exports['keymanager']);
$exports['keymanager'] = $keymanager;
}
$exportsmenu = [];
// Generate the data for the exports navigation selector menu.
foreach ($exports as $export) {
$exportsmenu[$export->link->out()] = $export->string;
}
// This navigation selector menu will contain the links to all available grade export plugin pages.
$exportsurlselect = new \url_select($exportsmenu, $this->exportactiveurl->out(false), null,
'gradesexportactionselect');
$data['exportselector'] = $exportsurlselect->export_for_template($output);
return $data;
}
}
@@ -0,0 +1,63 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook exports key manager page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class export_key_manager_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/export_key_manager_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector and exports navigation selector.
$exportnavselectors = new export_action_bar($this->context,
new moodle_url('/grade/export/keymanager.php', ['id' => $courseid]), 'keymanager');
$data = $exportnavselectors->export_for_template($output);
// Add a button to the action bar with a link to the 'add user key' page.
$adduserkeylink = new moodle_url('/grade/export/key.php', ['courseid' => $courseid]);
$adduserkeybutton = new \single_button($adduserkeylink, get_string('adduserkey', 'userkey'),
'get', true);
$data['adduserkeybutton'] = $adduserkeybutton->export_for_template($output);
return $data;
}
}
@@ -0,0 +1,73 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook publish export page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class export_publish_action_bar extends action_bar {
/** @var string $activeplugin The plugin of the current export grades page (xml, ods, ...). */
protected $activeplugin;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param string $activeplugin The plugin of the current export grades page (xml, ods, ...).
*/
public function __construct(\context $context, string $activeplugin) {
parent::__construct($context);
$this->activeplugin = $activeplugin;
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/export_publish_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Add a back button to the action bar.
$backlink = new moodle_url("/grade/export/{$this->activeplugin}/index.php", ['id' => $courseid]);
$backbutton = new \single_button($backlink, get_string('back'), 'get');
return [
'backbutton' => $backbutton->export_for_template($output)
];
}
}
+191
View File
@@ -0,0 +1,191 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the general action bar in the gradebook pages.
*
* This class is responsible for rendering the general navigation select menu in the gradebook pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class general_action_bar extends action_bar {
/** @var moodle_url $activeurl The URL that should be set as active in the URL selector element. */
protected $activeurl;
/**
* The type of the current gradebook page (report, settings, import, export, scales, outcomes, letters).
*
* @var string $activetype
*/
protected $activetype;
/** @var string $activeplugin The plugin of the current gradebook page (grader, fullview, ...). */
protected $activeplugin;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param moodle_url $activeurl The URL that should be set as active in the URL selector element.
* @param string $activetype The type of the current gradebook page (report, settings, import, export, scales,
* outcomes, letters).
* @param string $activeplugin The plugin of the current gradebook page (grader, fullview, ...).
*/
public function __construct(\context $context, moodle_url $activeurl, string $activetype, string $activeplugin) {
parent::__construct($context);
$this->activeurl = $activeurl;
$this->activetype = $activetype;
$this->activeplugin = $activeplugin;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$urlselect = $this->get_action_selector();
if (is_null($urlselect)) {
return [];
}
return [
'generalnavselector' => $urlselect->export_for_template($output),
];
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/general_action_bar';
}
/**
* Returns the URL selector object.
*
* @return \url_select|null The URL select object.
*/
private function get_action_selector(): ?\url_select {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return null;
}
$courseid = $this->context->instanceid;
$plugininfo = grade_get_plugin_info($courseid, $this->activetype, $this->activeplugin);
$menu = [];
$viewgroup = [];
$setupgroup = [];
$moregroup = [];
foreach ($plugininfo as $plugintype => $plugins) {
// Skip if the plugintype value is 'strings'. This particular item only returns an array of strings
// which we do not need.
if ($plugintype == 'strings') {
continue;
}
// If $plugins is actually the definition of a child-less parent link.
if (!empty($plugins->id)) {
$string = $plugins->string;
if (!empty($plugininfo[$this->activetype]->parent)) {
$string = $plugininfo[$this->activetype]->parent->string;
}
$menu[$plugins->link->out(false)] = $string;
continue;
}
foreach ($plugins as $key => $plugin) {
// Depending on the plugin type, include the plugin to the appropriate item group for the URL selector
// element.
switch ($plugintype) {
case 'report':
$viewgroup[$plugin->link->out(false)] = $plugin->string;
break;
case 'settings':
$setupgroup[$plugin->link->out(false)] = $plugin->string;
break;
case 'scale':
// We only need the link to the 'view scales' page, otherwise skip and continue to the next
// plugin.
if ($key !== 'view') {
continue 2;
}
$moregroup[$plugin->link->out(false)] = get_string('scales');
break;
case 'outcome':
// We only need the link to the 'outcomes used in course' page, otherwise skip and continue to
// the next plugin.
if ($key !== 'course') {
continue 2;
}
$moregroup[$plugin->link->out(false)] = get_string('outcomes', 'grades');
break;
case 'letter':
// We only need the link to the 'view grade letters' page, otherwise skip and continue to the
// next plugin.
if ($key !== 'view') {
continue 2;
}
$moregroup[$plugin->link->out(false)] = get_string('gradeletters', 'grades');
break;
case 'import':
$link = new moodle_url('/grade/import/index.php', ['id' => $courseid]);
// If the link to the grade import options is already added to the group, skip and continue to
// the next plugin.
if (array_key_exists($link->out(false), $moregroup)) {
continue 2;
}
$moregroup[$link->out(false)] = get_string('import', 'grades');
break;
case 'export':
$link = new moodle_url('/grade/export/index.php', ['id' => $courseid]);
// If the link to the grade export options is already added to the group, skip and continue to
// the next plugin.
if (array_key_exists($link->out(false), $moregroup)) {
continue 2;
}
$moregroup[$link->out(false)] = get_string('export', 'grades');
break;
}
}
}
if (!empty($viewgroup)) {
$menu[][get_string('view')] = $viewgroup;
}
if (!empty($setupgroup)) {
$menu[][get_string('setup', 'grades')] = $setupgroup;
}
if (!empty($moregroup)) {
$menu[][get_string('moremenu')] = $moregroup;
}
return new \url_select($menu, $this->activeurl->out(false), null, 'gradesactionselect');
}
}
@@ -0,0 +1,61 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the grade letters page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_letters_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/grade_letters_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$data = [];
// If in the course context, we should display the general navigation selector in gradebook.
if ($this->context->contextlevel === CONTEXT_COURSE) {
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context, new moodle_url('/grade/edit/letter/index.php',
['id' => $this->context->id]), 'letter', 'view');
$data = $generalnavselector->export_for_template($output);
}
// Add a button to the action bar with a link to the 'edit grade letters' page.
$editbuttonlink = new moodle_url('/grade/edit/letter/index.php', ['id' => $this->context->id, 'edit' => 1]);
$editbutton = new \single_button($editbuttonlink, get_string('edit'), 'get', true);
$data['editbutton'] = $editbutton->export_for_template($output);
return $data;
}
}
@@ -0,0 +1,77 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook setup pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gradebook_setup_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/gradebook_setup_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
global $CFG;
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context,
new moodle_url('/grade/edit/tree/index.php', ['id' => $courseid]), 'settings', 'setup');
$data = $generalnavselector->export_for_template($output);
// Add a button to the action bar with a link to the 'add grade item' page.
$addgradeitemlink = new moodle_url('/grade/edit/tree/item.php', ['courseid' => $courseid]);
$addgradeitembutton = new \single_button($addgradeitemlink, get_string('additem', 'grades'), 'get');
$data['addgradeitembutton'] = $addgradeitembutton->export_for_template($output);
// If outcomes are enabled, add a button to the action bar with a link to the 'add outcome item' page.
if (!empty($CFG->enableoutcomes)) {
$addoutcomeitemlink = new moodle_url('/grade/edit/tree/outcomeitem.php', ['courseid' => $courseid]);
$addoutcomeitembutton = new \single_button($addoutcomeitemlink, get_string('addoutcomeitem', 'grades'),
'get');
$data['addoutcomeitembutton'] = $addoutcomeitembutton->export_for_template($output);
}
// Add a button to the action bar with a link to the 'add category' page.
$addcategorylink = new moodle_url('/grade/edit/tree/category.php', ['courseid' => $courseid]);
$addcategorybutton = new \single_button($addcategorylink, get_string('addcategory', 'grades'), 'get');
$data['addcategorybutton'] = $addcategorybutton->export_for_template($output);
return $data;
}
}
+100
View File
@@ -0,0 +1,100 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook import pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class import_action_bar extends action_bar {
/** @var moodle_url $importactiveurl The URL that should be set as active in the imports URL selector element. */
protected $importactiveurl;
/** @var string $activeplugin The plugin of the current import grades page (xml, csv, ...). */
protected $activeplugin;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param moodle_url $importactiveurl The URL that should be set as active in the imports URL selector element.
* @param string $activeplugin The plugin of the current import grades page (xml, csv, ...).
*/
public function __construct(\context $context, moodle_url $importactiveurl, string $activeplugin) {
parent::__construct($context);
$this->importactiveurl = $importactiveurl;
$this->activeplugin = $activeplugin;
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/import_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context,
new moodle_url('/grade/import/index.php', ['id' => $courseid]), 'import', $this->activeplugin);
$data = $generalnavselector->export_for_template($output);
// Get all grades import plugins. If there isn't any available import plugins there is no need to create and
// display the imports navigation selector menu. Therefore, return only the current data.
if (!$imports = \grade_helper::get_plugins_import($courseid)) {
return $data;
}
// If imports key management is enabled, always display this item at the end of the list.
if (array_key_exists('keymanager', $imports)) {
$keymanager = $imports['keymanager'];
unset($imports['keymanager']);
$imports['keymanager'] = $keymanager;
}
$importsmenu = [];
// Generate the data for the imports navigation selector menu.
foreach ($imports as $import) {
$importsmenu[$import->link->out()] = $import->string;
}
// This navigation selector menu will contain the links to all available grade export plugin pages.
$importsurlselect = new \url_select($importsmenu, $this->importactiveurl->out(false), null,
'gradesimportactionselect');
$data['importselector'] = $importsurlselect->export_for_template($output);
return $data;
}
}
@@ -0,0 +1,63 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook import key manager page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class import_key_manager_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/import_key_manager_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
if ($this->context->contextlevel !== CONTEXT_COURSE) {
return [];
}
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector and imports navigation selector.
$importnavselectors = new import_action_bar($this->context,
new moodle_url('/grade/import/keymanager.php', ['id' => $courseid]), 'keymanager');
$data = $importnavselectors->export_for_template($output);
// Add a button to the action bar with a link to the 'add user key' page.
$adduserkeylink = new moodle_url('/grade/import/key.php', ['courseid' => $courseid]);
$adduserkeybutton = new \single_button($adduserkeylink, get_string('adduserkey', 'userkey'),
'get', true);
$data['adduserkeybutton'] = $adduserkeybutton->export_for_template($output);
return $data;
}
}
@@ -0,0 +1,95 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the manage outcomes page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class manage_outcomes_action_bar extends action_bar {
/** @var bool $hasoutcomes Whether there are existing outcomes. */
protected $hasoutcomes;
/**
* The class constructor.
*
* @param \context $context The context object.
* @param bool $hasoutcomes Whether there are existing outcomes.
*/
public function __construct(\context $context, bool $hasoutcomes) {
parent::__construct($context);
$this->hasoutcomes = $hasoutcomes;
}
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/manage_outcomes_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$data = [];
$courseid = 0;
// Display the following buttons only if the user is in course gradebook.
if ($this->context->contextlevel === CONTEXT_COURSE) {
$courseid = $this->context->instanceid;
// Add a button to the action bar with a link to the 'course outcomes' page.
$backlink = new moodle_url('/grade/edit/outcome/course.php', ['id' => $courseid]);
$backbutton = new \single_button($backlink, get_string('back'), 'get');
$data['backbutton'] = $backbutton->export_for_template($output);
// Add a button to the action bar with a link to the 'import outcomes' page. The import outcomes
// functionality is currently only available in the course context.
$importoutcomeslink = new moodle_url('/grade/edit/outcome/import.php', ['courseid' => $courseid]);
$importoutcomesbutton = new \single_button($importoutcomeslink, get_string('importoutcomes', 'grades'),
'get');
$data['importoutcomesbutton'] = $importoutcomesbutton->export_for_template($output);
}
// Add a button to the action bar with a link to the 'add new outcome' page.
$addoutcomelink = new moodle_url('/grade/edit/outcome/edit.php', ['courseid' => $courseid]);
$addoutcomebutton = new \single_button($addoutcomelink, get_string('outcomecreate', 'grades'),
'get', true);
$data['addoutcomebutton'] = $addoutcomebutton->export_for_template($output);
if ($this->hasoutcomes) {
// Add a button to the action bar which enables export of all existing outcomes.
$exportoutcomeslink = new moodle_url('/grade/edit/outcome/export.php',
['id' => $courseid, 'sesskey' => sesskey()]);
$exportoutcomesbutton = new \single_button($exportoutcomeslink, get_string('exportalloutcomes', 'grades'),
'get');
$data['exportoutcomesbutton'] = $exportoutcomesbutton->export_for_template($output);
}
return $data;
}
}
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use moodle_url;
/**
* Renderable class for the action bar elements in the gradebook scales page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class scales_action_bar extends action_bar {
/**
* Returns the template for the action bar.
*
* @return string
*/
public function get_template(): string {
return 'core_grades/scales_action_bar';
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$data = [];
$courseid = 0;
// If in the course context, we should display the general navigation selector in gradebook.
if ($this->context->contextlevel === CONTEXT_COURSE) {
$courseid = $this->context->instanceid;
// Get the data used to output the general navigation selector.
$generalnavselector = new general_action_bar($this->context,
new moodle_url('/grade/edit/scale/index.php', ['id' => $courseid]), 'scale', 'scale');
$data = $generalnavselector->export_for_template($output);
}
// Add a button to the action bar with a link to the 'add new scale' page.
$addnewscalelink = new moodle_url('/grade/edit/scale/edit.php', ['courseid' => $courseid]);
$addnewscalebutton = new \single_button($addnewscalelink, get_string('scalescustomcreate'),
'get', true);
$data['addnewscalebutton'] = $addnewscalebutton->export_for_template($output);
return $data;
}
}
+1 -1
View File
@@ -80,7 +80,7 @@ class edit_letter_form extends moodleform {
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons(!$admin);
$this->add_action_buttons();
}
}
+14 -8
View File
@@ -79,6 +79,18 @@ $override = $DB->record_exists('grade_letters', array('contextid' => $context->i
//if were viewing the letters
if (!$edit) {
$heading = get_string('gradeletters', 'grades');
$actionbar = new \core_grades\output\grade_letters_action_bar($context);
if ($admin) {
echo $OUTPUT->header();
$renderer = $PAGE->get_renderer('core_grades');
echo $renderer->render_action_bar($actionbar);
echo $OUTPUT->heading($heading);
} else {
print_grade_page_head($course->id, 'letter', 'view', $heading, false, false,
true, null, null, null, $actionbar);
}
$data = array();
@@ -92,16 +104,10 @@ if (!$edit) {
$max = $boundary - 0.01;
}
print_grade_page_head($COURSE->id, 'letter', 'view', get_string('gradeletters', 'grades'));
if (!empty($override)) {
echo $OUTPUT->notification(get_string('gradeletteroverridden', 'grades'), 'notifymessage');
}
$stredit = get_string('editgradeletters', 'grades');
$editlink = html_writer::nonempty_tag('div', html_writer::link($returnurl.$editparam, $stredit), array('class'=>'mdl-align'));
echo $editlink;
$table = new html_table();
$table->id = 'grade-letters-view';
$table->head = array(get_string('max', 'grades'), get_string('min', 'grades'), get_string('letter', 'grades'));
@@ -112,7 +118,6 @@ if (!$edit) {
$table->tablealign = 'center';
echo html_writer::table($table);
echo $editlink;
} else { //else we're editing
require_once('edit_form.php');
@@ -252,7 +257,8 @@ if (!$edit) {
redirect($returnurl);
}
print_grade_page_head($COURSE->id, 'letter', 'edit', get_string('editgradeletters', 'grades'));
print_grade_page_head($COURSE->id, 'letter', 'edit', get_string('editgradeletters', 'grades'),
false, false, false);
$mform->display();
}
+4 -2
View File
@@ -132,8 +132,10 @@ if ($data = data_submitted() and confirm_sesskey()) {
redirect('course.php?id='.$courseid); // we must redirect to get fresh data
}
/// Print header
print_grade_page_head($COURSE->id, 'outcome', 'course');
$actionbar = new \core_grades\output\course_outcomes_action_bar($context);
// Print header.
print_grade_page_head($COURSE->id, 'outcome', 'course', false, false, false,
true, null, null, null, $actionbar);
require('course_form.html');
-11
View File
@@ -61,17 +61,6 @@
</td>
</tr>
</table>
<?php
if (has_capability('moodle/grade:manageoutcomes', $context)) {
?>
<p class="mdl-align">
<a href="<?php echo $CFG->wwwroot ?>/grade/edit/outcome/index.php?id=<?php echo $courseid; ?>"><?php echo get_string('editoutcomes','grades'); ?></a>
</p>
<?php
}
?>
<input name="id" type="hidden" value="<?php echo $courseid?>"/>
<input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
</div>
+2 -7
View File
@@ -41,7 +41,7 @@ $PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
$systemcontext = context_system::instance();
$heading = null;
$heading = get_string('addoutcome', 'grades');
// a bit complex access control :-O
if ($id) {
@@ -74,7 +74,6 @@ if ($id) {
}
} else if ($courseid){
$heading = get_string('addoutcome', 'grades');
/// adding new outcome from course
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
require_login($course);
@@ -159,11 +158,7 @@ if ($mform->is_cancelled()) {
redirect($returnurl);
}
if ($courseid) {
print_grade_page_head($courseid, 'outcome', 'edit', $heading);
} else {
echo $OUTPUT->header();
}
print_grade_page_head($courseid ?: SITEID, 'outcome', 'edit', $heading, false, false, false);
if (!grade_scale::fetch_all_local($courseid) && !grade_scale::fetch_all_global()) {
echo $OUTPUT->confirm(get_string('noscales', 'grades'), $CFG->wwwroot.'/grade/edit/scale/edit.php?courseid='.$courseid, $returnurl);
+28 -20
View File
@@ -59,14 +59,19 @@ $navigation = grade_build_nav(__FILE__, get_string('outcomes', 'grades'), $cours
$upload_form = new import_outcomes_form();
// display import form
if (!$upload_form->get_data()) {
print_grade_page_head($courseid, 'outcome', 'import', get_string('importoutcomes', 'grades'));
if ($upload_form->is_cancelled()) {
redirect(new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]));
die;
}
print_grade_page_head($courseid, 'outcome', 'import', get_string('importoutcomes', 'grades'),
false, false, false);
if (!$upload_form->get_data()) { // Display the import form.
$upload_form->display();
echo $OUTPUT->footer();
die;
}
print_grade_page_head($courseid, 'outcome', 'import', get_string('importoutcomes', 'grades'));
$imported_file = $CFG->tempdir . '/outcomeimport/importedfile_'.time().'.csv';
make_temp_directory('outcomeimport');
@@ -99,6 +104,7 @@ if ($handle = fopen($imported_file, 'r')) {
$imported_headers = array(); // will later be initialized with the values found in the file
$fatal_error = false;
$errormessage = '';
// data should be separated by a ';'. *NOT* by a comma! TODO: version 2.0
// or whenever we can depend on PHP5, set the second parameter (8192) to 0 (unlimited line length) : the database can store over 128k per line.
@@ -124,11 +130,8 @@ if ($handle = fopen($imported_file, 'r')) {
}
}
if ($error) {
echo $OUTPUT->box_start('generalbox importoutcomenofile buttons');
echo get_string('importoutcomenofile', 'grades', $line);
echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get');
echo $OUTPUT->box_end();
$fatal_error = true;
$errormessage = get_string('importoutcomenofile', 'grades', $line);
break;
}
@@ -143,23 +146,16 @@ if ($handle = fopen($imported_file, 'r')) {
// sanity check #2: every line must have the same number of columns as there are
// headers. If not, processing stops.
if ( count($csv_data) != count($file_headers) ) {
echo $OUTPUT->box_start('generalbox importoutcomenofile');
echo get_string('importoutcomenofile', 'grades', $line);
echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get');
echo $OUTPUT->box_end();
$fatal_error = true;
//echo $OUTPUT->box(var_export($csv_data, true) ."<br />". var_export($header, true));
$errormessage = get_string('importoutcomenofile', 'grades', $line);
break;
}
// sanity check #3: all required fields must be present on the current line.
foreach ($headers as $header => $position) {
if ($csv_data[$imported_headers[$header]] == '') {
echo $OUTPUT->box_start('generalbox importoutcomenofile');
echo get_string('importoutcomenofile', 'grades', $line);
echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', array('courseid'=> $courseid)), get_string('back'), 'get');
echo $OUTPUT->box_end();
$fatal_error = true;
$errormessage = get_string('importoutcomenofile', 'grades', $line);
break;
}
}
@@ -182,7 +178,8 @@ if ($handle = fopen($imported_file, 'r')) {
if ($outcome) {
// already exists, print a message and skip.
echo $OUTPUT->box(get_string('importskippedoutcome', 'grades', $csv_data[$imported_headers['outcome_shortname']]));
echo $OUTPUT->notification(get_string('importskippedoutcome', 'grades',
$csv_data[$imported_headers['outcome_shortname']]), 'info', false);
continue;
}
@@ -196,7 +193,8 @@ if ($handle = fopen($imported_file, 'r')) {
$scale_id = key($scale);
} else {
if (!has_capability('moodle/course:managescales', $context)) {
echo $OUTPUT->box(get_string('importskippednomanagescale', 'grades', $csv_data[$imported_headers['outcome_shortname']]));
echo $OUTPUT->notification(get_string('importskippedoutcome', 'grades',
$csv_data[$imported_headers['outcome_shortname']]), 'warning', false);
continue;
} else {
// scale doesn't exists : create it.
@@ -233,7 +231,17 @@ if ($handle = fopen($imported_file, 'r')) {
$outcome_success_strings = new StdClass();
$outcome_success_strings->name = $outcome_data['fullname'];
$outcome_success_strings->id = $outcome_id;
echo $OUTPUT->box(get_string('importoutcomesuccess', 'grades', $outcome_success_strings));
echo $OUTPUT->notification(get_string('importoutcomesuccess', 'grades', $outcome_success_strings),
'success', false);
}
if ($fatal_error) {
echo $OUTPUT->notification($errormessage, 'error', false);
echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/import.php', ['courseid' => $courseid]),
get_string('back'), 'get');
} else {
echo $OUTPUT->single_button(new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]),
get_string('continue'), 'get');
}
} else {
echo $OUTPUT->box(get_string('importoutcomenofile', 'grades', 0));
+5 -2
View File
@@ -51,8 +51,11 @@ class import_outcomes_form extends moodleform {
$mform->addRule('userfile', get_string('required'), 'required', null, 'server');
$mform->addHelpButton('userfile', 'importoutcomes', 'grades');
$mform->addElement('submit', 'save', get_string('uploadthisfile'));
$buttonarray = [
$mform->createElement('submit', 'save', get_string('uploadthisfile')),
$mform->createElement('cancel')
];
$mform->addGroup($buttonarray, 'buttonar', '', ' ', false);
}
}
+13 -16
View File
@@ -50,6 +50,7 @@ if ($courseid) {
}
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
$context = context_system::instance();
}
/// return tracking object
@@ -113,7 +114,6 @@ if ($courseid) {
$caneditcoursescales = has_capability('moodle/course:managescales', $context);
} else {
echo $OUTPUT->header();
$caneditcoursescales = $caneditsystemscales;
}
@@ -122,7 +122,7 @@ $outcomes_tables = array();
$heading = get_string('outcomes', 'grades');
if ($courseid and $outcomes = grade_outcome::fetch_all_local($courseid)) {
$return = $OUTPUT->heading($strcustomoutcomes, 3, 'main');
$return = $OUTPUT->heading($strcustomoutcomes, 3, 'main mt-3');
$data = array();
foreach($outcomes as $outcome) {
$line = array();
@@ -172,7 +172,7 @@ if ($courseid and $outcomes = grade_outcome::fetch_all_local($courseid)) {
if ($outcomes = grade_outcome::fetch_all_global()) {
$return = $OUTPUT->heading($strstandardoutcome, 3, 'main');
$return = $OUTPUT->heading($strstandardoutcome, 3, 'main mt-3');
$data = array();
foreach($outcomes as $outcome) {
$line = array();
@@ -223,22 +223,19 @@ if ($outcomes = grade_outcome::fetch_all_global()) {
$outcomes_tables[] = $return;
}
if ($courseid) {
/// Print header
print_grade_page_head($courseid, 'outcome', 'edit', $heading);
}
$actionbar = new \core_grades\output\manage_outcomes_action_bar($context, !empty($outcomes_tables));
print_grade_page_head($courseid ?: SITEID, 'outcome', 'edit', $heading, false, false,
true, null, null, null, $actionbar);
foreach($outcomes_tables as $table) {
echo $table;
// If there are existing outcomes, output the outcome tables.
if (!empty($outcomes_tables)) {
foreach ($outcomes_tables as $table) {
echo $table;
}
} else {
echo $OUTPUT->notification(get_string('noexistingoutcomes', 'grades'), 'info', false);
}
echo $OUTPUT->container_start('buttons');
echo $OUTPUT->single_button(new moodle_url('edit.php', array('courseid'=>$courseid)), $strcreatenewoutcome);
if ( !empty($outcomes_tables) ) {
echo $OUTPUT->single_button(new moodle_url('export.php', array('id'=>$courseid, 'sesskey'=>sesskey())), get_string('exportalloutcomes', 'grades'));
}
echo $OUTPUT->container_end();
echo $OUTPUT->footer();
/**
+1 -4
View File
@@ -36,12 +36,9 @@ navigation_node::override_active_url(new moodle_url('/grade/edit/scale/index.php
array('id' => $courseid)));
$systemcontext = context_system::instance();
$heading = '';
// a bit complex access control :-O
if ($id) {
$heading = get_string('editscale', 'grades');
/// editing existing scale
if (!$scale_rec = $DB->get_record('scale', array('id' => $id))) {
print_error('invalidscaleid');
@@ -68,7 +65,6 @@ if ($id) {
}
} else if ($courseid){
$heading = get_string('addscale', 'grades');
/// adding new scale from course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
print_error('invalidcourseid');
@@ -147,6 +143,7 @@ if ($mform->is_cancelled()) {
redirect($returnurl);
}
$heading = $id ? get_string('editscale', 'grades') : get_string('addscale', 'grades');
print_grade_page_head($COURSE->id, 'scale', null, $heading, false, false, false);
$mform->display();
+25 -9
View File
@@ -43,6 +43,7 @@ if ($courseid) {
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('scales');
$context = context_system::instance();
}
/// return tracking object
@@ -54,7 +55,6 @@ $strcustomscales = get_string('scalescustom');
$strname = get_string('name');
$strdelete = get_string('delete');
$stredit = get_string('edit');
$srtcreatenewscale = get_string('scalescustomcreate');
$strused = get_string('used');
$stredit = get_string('edit');
@@ -164,16 +164,32 @@ if ($scales = grade_scale::fetch_all_global()) {
$table2->data = $data;
}
$actionbar = new \core_grades\output\scales_action_bar($context);
if ($courseid) {
print_grade_page_head($courseid, 'scale', 'scale', get_string('coursescales', 'grades'));
print_grade_page_head($courseid, 'scale', 'scale', get_string('coursescales', 'grades'),
false, false, true, null, null, null, $actionbar);
} else {
$renderer = $PAGE->get_renderer('core_grades');
echo $renderer->render_action_bar($actionbar);
echo $OUTPUT->heading(get_string('scales', 'core'));
}
echo $OUTPUT->heading($strcustomscales, 3, 'main');
echo html_writer::table($table);
echo $OUTPUT->heading($strstandardscale, 3, 'main');
echo html_writer::table($table2);
echo $OUTPUT->container_start('buttons');
echo $OUTPUT->single_button(new moodle_url('edit.php', array('courseid'=>$courseid)), $srtcreatenewscale);
echo $OUTPUT->container_end();
$hascustomscales = !empty($table->data);
$hasstandardscales = !empty($table2->data);
// If there are custom scales available in this context, output the custom scales table and a heading.
if ($hascustomscales) {
echo $OUTPUT->heading($strcustomscales, 3, 'main mt-3');
echo html_writer::table($table);
}
// If there are standard scales available in this context, output the standard scales table and a heading.
if ($hasstandardscales) {
echo $OUTPUT->heading($strstandardscale, 3, 'main mt-3');
echo html_writer::table($table2);
}
// If the are no available scales, display a notification.
if (!$hascustomscales && !$hasstandardscales) {
echo $OUTPUT->notification(get_string('noexistingscales', 'grades'), 'info', false);
}
echo $OUTPUT->footer();
+1 -1
View File
@@ -140,7 +140,7 @@ class course_settings_form extends moodleform {
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$this->add_action_buttons();
$this->add_action_buttons(false);
}
}
+1 -8
View File
@@ -45,18 +45,13 @@ $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'settings', 'cour
$strgrades = get_string('grades');
$pagename = get_string('coursesettings', 'grades');
$returnurl = $CFG->wwwroot.'/grade/index.php?id='.$course->id;
$mform = new course_settings_form();
$settings = grade_get_settings($course->id);
$mform->set_data($settings);
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
if ($data = $mform->get_data()) {
$data = (array)$data;
$general = array('displaytype', 'decimalpoints', 'aggregationposition', 'minmaxtouse');
foreach ($data as $key=>$value) {
@@ -76,8 +71,6 @@ if ($mform->is_cancelled()) {
grade_force_full_regrading($courseid);
}
}
redirect($returnurl);
}
print_grade_page_head($courseid, 'settings', 'coursesettings', get_string('coursegradesettings', 'grades'));
+3 -10
View File
@@ -245,7 +245,9 @@ if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_check
$recreatetree = true;
}
print_grade_page_head($courseid, 'settings', 'setup', get_string('gradebooksetup', 'grades'));
$actionbar = new \core_grades\output\gradebook_setup_action_bar($context);
print_grade_page_head($courseid, 'settings', 'setup', get_string('gradebooksetup', 'grades'),
false, false, true, null, null, null, $actionbar);
// Print Table of categories and items
echo $OUTPUT->box_start('gradetreebox generalbox');
@@ -286,15 +288,6 @@ echo $OUTPUT->container_start('buttons mdl-align');
if ($moving) {
echo $OUTPUT->single_button(new moodle_url('index.php', array('id'=>$course->id)), get_string('cancel'), 'get');
} else {
echo $OUTPUT->single_button(new moodle_url('item.php', array('courseid' => $course->id)), get_string('additem',
'grades'), 'get');
if (!empty($CFG->enableoutcomes)) {
echo $OUTPUT->single_button(new moodle_url('outcomeitem.php', array('courseid'=>$course->id)), get_string('addoutcomeitem', 'grades'), 'get');
}
echo $OUTPUT->single_button(new moodle_url('category.php', array('courseid' => $course->id)), get_string('addcategory',
'grades'), 'get');
//echo $OUTPUT->(new moodle_url('index.php', array('id'=>$course->id, 'action'=>'autosort')), get_string('autosort', 'grades'), 'get');
}
echo $OUTPUT->container_end();
+56
View File
@@ -0,0 +1,56 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Redirects the user to a default grades export plugin page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
// Course ID.
$courseid = required_param('id', PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/export/index.php', ['id' => $courseid]));
// Basic access checks.
if (!$course = $DB->get_record('course', ['id' => $courseid])) {
throw new moodle_exception('invalidcourseid', 'error');
}
require_login($course);
$context = context_course::instance($courseid);
require_capability('moodle/grade:export', $context);
$exportplugins = core_component::get_plugin_list('gradeexport');
if (!empty($exportplugins)) {
$exportplugin = array_key_first($exportplugins);
$url = new moodle_url("/grade/export/{$exportplugin}/index.php", ['id' => $courseid]);
redirect($url);
}
// Otherwise, output the page with a notification stating that there are no available grade import options.
$PAGE->set_title(get_string('export', 'grades'));
$PAGE->set_pagelayout('incourse');
$PAGE->set_heading($course->fullname);
$PAGE->set_pagetype('course-view-' . $course->format);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('export', 'grades'));
echo html_writer::div($OUTPUT->notification(get_string('nogradeexport', 'debug'), 'error'), 'mt-3');
echo $OUTPUT->footer();
+3
View File
@@ -80,6 +80,7 @@ if ($id and $delete) {
if (!$confirm) {
$PAGE->set_title(get_string('deleteselectedkey'));
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
echo $OUTPUT->header();
$optionsyes = array('id'=>$id, 'delete'=>1, 'courseid'=>$courseid, 'sesskey'=>sesskey(), 'confirm'=>1);
$optionsno = array('id'=>$courseid);
@@ -133,7 +134,9 @@ $PAGE->navbar->add($strheading);
/// Print header
$PAGE->set_title($strkeys);
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
echo $OUTPUT->header();
echo $OUTPUT->heading($strheading);
$editform->display();
echo $OUTPUT->footer();
+4 -6
View File
@@ -45,7 +45,10 @@ if (!isset($plugins['keymanager'])) {
print_error('nopermissions');
}
print_grade_page_head($course->id, 'export', 'keymanager', get_string('keymanager', 'grades'));
$actionbar = new \core_grades\output\export_key_manager_action_bar($context);
print_grade_page_head($COURSE->id, 'export', 'keymanager',
get_string('keymanager', 'grades'), false, false, true, null,
null, null, $actionbar);
$stredit = get_string('edit');
$strdelete = get_string('delete');
@@ -81,10 +84,5 @@ $table->align = array('left', 'left', 'left', 'center');
$table->width = '90%';
$table->data = $data;
echo html_writer::table($table);
echo $OUTPUT->container_start('buttons mdl-align');
echo $OUTPUT->single_button(new moodle_url('key.php', array('courseid'=>$course->id)), get_string('newuserkey', 'userkey'));
echo $OUTPUT->container_end();
echo $OUTPUT->footer();
+4 -1
View File
@@ -37,7 +37,10 @@ require_capability('gradeexport/ods:view', $context);
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'ods', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'));
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'ods');
print_grade_page_head($COURSE->id, 'export', 'ods',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
+4 -1
View File
@@ -33,7 +33,10 @@ $context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/ods:view', $context);
print_grade_page_head($COURSE->id, 'export', 'ods', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'));
$actionbar = new \core_grades\output\export_action_bar($context, $PAGE->url, 'ods');
print_grade_page_head($COURSE->id, 'export', 'ods',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_ods'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
+4 -1
View File
@@ -37,7 +37,10 @@ require_capability('gradeexport/txt:view', $context);
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'txt', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'));
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'txt');
print_grade_page_head($COURSE->id, 'export', 'txt',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
+4 -1
View File
@@ -33,7 +33,10 @@ $context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/txt:view', $context);
print_grade_page_head($COURSE->id, 'export', 'txt', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'));
$actionbar = new \core_grades\output\export_action_bar($context, $PAGE->url, 'txt');
print_grade_page_head($COURSE->id, 'export', 'txt',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_txt'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
+4 -4
View File
@@ -29,7 +29,7 @@ Feature: I need to export grades as text
@javascript
Scenario: Export grades as text
When I navigate to "Export > Plain text file" in the course gradebook
When I navigate to "Plain text file" export page in the course gradebook
And I expand all fieldsets
And I click on "Course total" "checkbox"
And I set the field "Grade export decimal places" to "1"
@@ -41,7 +41,7 @@ Feature: I need to export grades as text
@javascript
Scenario: Export grades as text using real
When I navigate to "Export > Plain text file" in the course gradebook
When I navigate to "Plain text file" export page in the course gradebook
And I expand all fieldsets
And I set the following fields to these values:
| Real | 1 |
@@ -52,7 +52,7 @@ Feature: I need to export grades as text
@javascript
Scenario: Export grades as text using percentages and letters
When I navigate to "Export > Plain text file" in the course gradebook
When I navigate to "Plain text file" export page in the course gradebook
And I set the following fields to these values:
| Percentage | 1 |
| Letter | 1 |
@@ -65,7 +65,7 @@ Feature: I need to export grades as text
@javascript
Scenario: Export grades as text using real, percentages and letters
When I navigate to "Export > Plain text file" in the course gradebook
When I navigate to "Plain text file" export page in the course gradebook
And I set the following fields to these values:
| Real | 1 |
| Percentage | 1 |
+4 -1
View File
@@ -37,7 +37,10 @@ require_capability('gradeexport/xls:view', $context);
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'xls', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'));
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'xls');
print_grade_page_head($COURSE->id, 'export', 'xls',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
+4 -1
View File
@@ -33,7 +33,10 @@ $context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xls:view', $context);
print_grade_page_head($COURSE->id, 'export', 'xls', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'));
$actionbar = new \core_grades\output\export_action_bar($context, $PAGE->url, 'xls');
print_grade_page_head($COURSE->id, 'export', 'xls',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xls'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
+4 -1
View File
@@ -37,7 +37,10 @@ require_capability('gradeexport/xml:view', $context);
// If you use this method without this check, will break the direct grade exporting (without publishing).
$key = optional_param('key', '', PARAM_RAW);
if (!empty($CFG->gradepublishing) && !empty($key)) {
print_grade_page_head($COURSE->id, 'export', 'xml', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'));
$actionbar = new \core_grades\output\export_publish_action_bar($context, 'xml');
print_grade_page_head($COURSE->id, 'export', 'xml',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'),
false, false, true, null, null, null, $actionbar);
}
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
+4 -1
View File
@@ -33,7 +33,10 @@ $context = context_course::instance($id);
require_capability('moodle/grade:export', $context);
require_capability('gradeexport/xml:view', $context);
print_grade_page_head($COURSE->id, 'export', 'xml', get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'));
$actionbar = new \core_grades\output\export_action_bar($context, $PAGE->url, 'xml');
print_grade_page_head($COURSE->id, 'export', 'xml',
get_string('exportto', 'grades') . ' ' . get_string('pluginname', 'gradeexport_xml'),
false, false, true, null, null, null, $actionbar);
export_verify_grades($COURSE->id);
if (!empty($CFG->gradepublishing)) {
+1 -1
View File
@@ -31,7 +31,7 @@ Feature: I need to export grades as xml
@javascript
Scenario: Export grades as XML
When I navigate to "Export > XML file" in the course gradebook
When I navigate to "XML file" export page in the course gradebook
And I expand all fieldsets
And I set the field "Grade export decimal places" to "1"
And I press "Download"
+2 -1
View File
@@ -51,8 +51,9 @@ $separatemode = (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and
!has_capability('moodle/site:accessallgroups', $context));
$currentgroup = groups_get_course_group($course);
$actionbar = new \core_grades\output\import_action_bar($context, $PAGE->url, 'csv');
print_grade_page_head($course->id, 'import', 'csv', get_string('importcsv', 'grades'), false, false, true,
'importcsv', 'grades');
'importcsv', 'grades', null, $actionbar);
$renderer = $PAGE->get_renderer('gradeimport_csv');
+2 -1
View File
@@ -47,8 +47,9 @@ $separatemode = (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and
!has_capability('moodle/site:accessallgroups', $context));
$currentgroup = groups_get_course_group($course);
$actionbar = new \core_grades\output\import_action_bar($context, $PAGE->url, 'direct');
print_grade_page_head($course->id, 'import', 'direct', get_string('pluginname', 'gradeimport_direct'), false, false, true,
'userdata', 'gradeimport_direct');
'userdata', 'gradeimport_direct', null, $actionbar);
$renderer = $PAGE->get_renderer('gradeimport_csv');
+56
View File
@@ -0,0 +1,56 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Redirects the user to a default grades import plugin page.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
// Course ID.
$courseid = required_param('id', PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/import/index.php', ['id' => $courseid]));
// Basic access checks.
if (!$course = $DB->get_record('course', ['id' => $courseid])) {
throw new moodle_exception('invalidcourseid', 'error');
}
require_login($course);
$context = context_course::instance($courseid);
require_capability('moodle/grade:import', $context);
$importplugins = core_component::get_plugin_list('gradeimport');
if (!empty($importplugins)) {
$importplugin = array_key_first($importplugins);
$url = new moodle_url("/grade/import/{$importplugin}/index.php", ['id' => $courseid]);
redirect($url);
}
// Otherwise, output the page with a notification stating that there are no available grade import options.
$PAGE->set_title(get_string('import', 'grades'));
$PAGE->set_pagelayout('incourse');
$PAGE->set_heading($course->fullname);
$PAGE->set_pagetype('course-view-' . $course->format);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('import', 'grades'));
echo html_writer::div($OUTPUT->notification(get_string('nogradeimport', 'grades'), 'error'), 'mt-3');
echo $OUTPUT->footer();
+3
View File
@@ -80,6 +80,7 @@ if ($id and $delete) {
if (!$confirm) {
$PAGE->set_title(get_string('deleteselectedkey'));
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
echo $OUTPUT->header();
$optionsyes = array('id'=>$id, 'delete'=>1, 'courseid'=>$courseid, 'sesskey'=>sesskey(), 'confirm'=>1);
$optionsno = array('id'=>$courseid);
@@ -133,7 +134,9 @@ $PAGE->navbar->add($strheading);
/// Print header
$PAGE->set_title($strkeys);
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('grades');
echo $OUTPUT->header();
echo $OUTPUT->heading($strheading);
$editform->display();
echo $OUTPUT->footer();
+3 -6
View File
@@ -45,7 +45,9 @@ if (!isset($plugins['keymanager'])) {
print_error('nopermissions');
}
print_grade_page_head($course->id, 'import', 'keymanager', get_string('keymanager', 'grades'));
$actionbar = new \core_grades\output\import_key_manager_action_bar($context);
print_grade_page_head($course->id, 'import', 'keymanager', get_string('keymanager', 'grades'),
false, false, true, 'importcsv', 'grades', null, $actionbar);
$stredit = get_string('edit');
$strdelete = get_string('delete');
@@ -78,10 +80,5 @@ $table->align = array('left', 'left', 'left', 'center');
$table->width = '90%';
$table->data = $data;
echo html_writer::table($table);
echo $OUTPUT->container_start('buttons mdl-align');
echo $OUTPUT->single_button(new moodle_url('key.php', array('courseid'=>$course->id)), get_string('newuserkey', 'userkey'));
echo $OUTPUT->container_end();
echo $OUTPUT->footer();
+3 -2
View File
@@ -87,8 +87,9 @@ if ($data = $mform->get_data()) {
}
}
print_grade_page_head($COURSE->id, 'import', 'xml',
get_string('importxml', 'grades'), false, false, true, 'importxml', 'gradeimport_xml');
$actionbar = new \core_grades\output\import_action_bar($context, $PAGE->url, 'xml');
print_grade_page_head($COURSE->id, 'import', 'xml', get_string('importxml', 'grades'),
false, false, true, 'importxml', 'gradeimport_xml', null, $actionbar);
$mform->display();
+75 -196
View File
@@ -25,6 +25,9 @@
require_once($CFG->libdir . '/gradelib.php');
require_once($CFG->dirroot . '/grade/export/lib.php');
use \core_grades\output\action_bar;
use \core_grades\output\general_action_bar;
/**
* This class iterates over all users that are graded in a course.
* Returns detailed info about users and their grades.
@@ -702,141 +705,6 @@ function print_natural_aggregation_upgrade_notice($courseid, $context, $thispage
}
}
/**
* Print grading plugin selection popup form.
*
* @param array $plugin_info An array of plugins containing information for the selector
* @param boolean $return return as string
*
* @return nothing or string if $return true
*/
function print_grade_plugin_selector($plugin_info, $active_type, $active_plugin, $return=false) {
global $CFG, $OUTPUT, $PAGE;
$menu = array();
$count = 0;
$active = '';
foreach ($plugin_info as $plugin_type => $plugins) {
if ($plugin_type == 'strings') {
continue;
}
$first_plugin = reset($plugins);
$sectionname = $plugin_info['strings'][$plugin_type];
$section = array();
foreach ($plugins as $plugin) {
$link = $plugin->link->out(false);
$section[$link] = $plugin->string;
$count++;
if ($plugin_type === $active_type and $plugin->id === $active_plugin) {
$active = $link;
}
}
if ($section) {
$menu[] = array($sectionname=>$section);
}
}
// finally print/return the popup form
if ($count > 1) {
$select = new url_select($menu, $active, null, 'choosepluginreport');
$select->set_label(get_string('gradereport', 'grades'), array('class' => 'accesshide'));
if ($return) {
return $OUTPUT->render($select);
} else {
echo $OUTPUT->render($select);
}
} else {
// only one option - no plugin selector needed
return '';
}
}
/**
* Print grading plugin selection tab-based navigation.
*
* @param string $active_type type of plugin on current page - import, export, report or edit
* @param string $active_plugin active plugin type - grader, user, cvs, ...
* @param array $plugin_info Array of plugins
* @param boolean $return return as string
*
* @return nothing or string if $return true
*/
function grade_print_tabs($active_type, $active_plugin, $plugin_info, $return=false) {
global $CFG, $COURSE;
if (!isset($currenttab)) { //TODO: this is weird
$currenttab = '';
}
$tabs = array();
$top_row = array();
$bottom_row = array();
$inactive = array($active_plugin);
$activated = array($active_type);
$count = 0;
$active = '';
foreach ($plugin_info as $plugin_type => $plugins) {
if ($plugin_type == 'strings') {
continue;
}
// If $plugins is actually the definition of a child-less parent link:
if (!empty($plugins->id)) {
$string = $plugins->string;
if (!empty($plugin_info[$active_type]->parent)) {
$string = $plugin_info[$active_type]->parent->string;
}
$top_row[] = new tabobject($plugin_type, $plugins->link, $string);
continue;
}
$first_plugin = reset($plugins);
$url = $first_plugin->link;
if ($plugin_type == 'report') {
$url = $CFG->wwwroot.'/grade/report/index.php?id='.$COURSE->id;
}
$top_row[] = new tabobject($plugin_type, $url, $plugin_info['strings'][$plugin_type]);
if ($active_type == $plugin_type) {
foreach ($plugins as $plugin) {
$bottom_row[] = new tabobject($plugin->id, $plugin->link, $plugin->string);
if ($plugin->id == $active_plugin) {
$inactive = array($plugin->id);
}
}
}
}
// Do not display rows that contain only one item, they are not helpful.
if (count($top_row) > 1) {
$tabs[] = $top_row;
}
if (count($bottom_row) > 1) {
$tabs[] = $bottom_row;
}
if (empty($tabs)) {
return;
}
$rv = html_writer::div(print_tabs($tabs, $active_plugin, $inactive, $activated, true), 'grade-navigation');
if ($return) {
return $rv;
} else {
echo $rv;
}
}
/**
* grade_get_plugin_info
*
@@ -966,31 +834,29 @@ class grade_plugin_info {
}
/**
* Prints the page headers, breadcrumb trail, page heading, (optional) dropdown navigation menu and
* (optional) navigation tabs for any gradebook page. All gradebook pages MUST use these functions
* in favour of the usual print_header(), print_header_simple(), print_heading() etc.
* !IMPORTANT! Use of tabs.php file in gradebook pages is forbidden unless tabs are switched off at
* the site level for the gradebook ($CFG->grade_navmethod = GRADE_NAVMETHOD_DROPDOWN).
* Prints the page headers, breadcrumb trail, page heading, (optional) navigation and for any gradebook page.
* All gradebook pages MUST use these functions in favour of the usual print_header(), print_header_simple(),
* print_heading() etc.
*
* @param int $courseid Course id
* @param string $active_type The type of the current page (report, settings,
* import, export, scales, outcomes, letters)
* @param string $active_plugin The plugin of the current page (grader, fullview etc...)
* @param string $heading The heading of the page. Tries to guess if none is given
* @param int $courseid Course id
* @param string $active_type The type of the current page (report, settings,
* import, export, scales, outcomes, letters)
* @param string|null $active_plugin The plugin of the current page (grader, fullview etc...)
* @param string|bool $heading The heading of the page. Tries to guess if none is given
* @param boolean $return Whether to return (true) or echo (false) the HTML generated by this function
* @param string $bodytags Additional attributes that will be added to the <body> tag
* @param string $buttons Additional buttons to display on the page
* @param boolean $shownavigation should the gradebook navigation drop down (or tabs) be shown?
* @param string $headerhelpidentifier The help string identifier if required.
* @param string $headerhelpcomponent The component for the help string.
* @param stdClass $user The user object for use with the user context header.
*
* @param string|bool $buttons Additional buttons to display on the page
* @param boolean $shownavigation should the gradebook navigation be shown?
* @param string|null $headerhelpidentifier The help string identifier if required.
* @param string|null $headerhelpcomponent The component for the help string.
* @param stdClass|null $user The user object for use with the user context header.
* @param actionbar|null $actionbar The actions bar which will be displayed on the page if $shownavigation is set
* to true. If $actionbar is not explicitly defined, the general action bar
* (\core_grades\output\general_action_bar) will be used by default.
* @return string HTML code or nothing if $return == false
*/
function print_grade_page_head($courseid, $active_type, $active_plugin=null,
$heading = false, $return=false,
$buttons=false, $shownavigation=true, $headerhelpidentifier = null, $headerhelpcomponent = null,
$user = null) {
function print_grade_page_head(int $courseid, string $active_type, ?string $active_plugin = null, $heading = false,
bool $return = false, $buttons = false, bool $shownavigation = true, ?string $headerhelpidentifier = null,
?string $headerhelpcomponent = null, ?stdClass $user = null, ?action_bar $actionbar = null) {
global $CFG, $OUTPUT, $PAGE;
// Put a warning on all gradebook pages if the course has modules currently scheduled for background deletion.
@@ -1024,6 +890,8 @@ function print_grade_page_head($courseid, $active_type, $active_plugin=null,
}
$PAGE->set_title(get_string('grades') . ': ' . $stractive_type);
$PAGE->set_heading($title);
$PAGE->set_secondary_active_tab('grades');
if ($buttons instanceof single_button) {
$buttons = $OUTPUT->render($buttons);
}
@@ -1049,53 +917,46 @@ function print_grade_page_head($courseid, $active_type, $active_plugin=null,
}
if ($shownavigation) {
$navselector = null;
if ($courseid != SITEID &&
($CFG->grade_navmethod == GRADE_NAVMETHOD_COMBO || $CFG->grade_navmethod == GRADE_NAVMETHOD_DROPDOWN)) {
// It's absolutely essential that this grade plugin selector is shown after the user header. Just ask Fred.
$navselector = print_grade_plugin_selector($plugin_info, $active_type, $active_plugin, true);
if ($return) {
$returnval .= $navselector;
} else if (!isset($user)) {
echo $navselector;
}
}
$output = '';
// Add a help dialogue box if provided.
if (isset($headerhelpidentifier)) {
$output = $OUTPUT->heading_with_help($heading, $headerhelpidentifier, $headerhelpcomponent);
} else {
if (isset($user)) {
$output = $OUTPUT->context_header(
array(
'heading' => html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id,
'course' => $courseid)), fullname($user)),
'user' => $user,
'usercontext' => context_user::instance($user->id)
), 2
) . $navselector;
} else {
$output = $OUTPUT->heading($heading);
}
$renderer = $PAGE->get_renderer('core_grades');
// If the navigation action bar is not explicitly defined, use the general (default) action bar.
if (!$actionbar) {
$actionbar = new general_action_bar($PAGE->context, $PAGE->url, $active_type, $active_plugin);
}
if ($return) {
$returnval .= $output;
$returnval .= $renderer->render_action_bar($actionbar);
} else {
echo $output;
}
if ($courseid != SITEID &&
($CFG->grade_navmethod == GRADE_NAVMETHOD_COMBO || $CFG->grade_navmethod == GRADE_NAVMETHOD_TABS)) {
$returnval .= grade_print_tabs($active_type, $active_plugin, $plugin_info, $return);
echo $renderer->render_action_bar($actionbar);
}
}
$returnval .= print_natural_aggregation_upgrade_notice($courseid,
context_course::instance($courseid),
$PAGE->url,
$return);
$output = '';
// Add a help dialogue box if provided.
if (isset($headerhelpidentifier)) {
$output = $OUTPUT->heading_with_help($heading, $headerhelpidentifier, $headerhelpcomponent);
} else {
if (isset($user)) {
$output = $OUTPUT->context_header(
array(
'heading' => html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id,
'course' => $courseid)), fullname($user)),
'user' => $user,
'usercontext' => context_user::instance($user->id)
), 2
);
} else {
$output = $OUTPUT->heading($heading);
}
}
if ($return) {
$returnval .= $output;
} else {
echo $output;
}
$returnval .= print_natural_aggregation_upgrade_notice($courseid, context_course::instance($courseid), $PAGE->url,
$return);
if ($return) {
return $returnval;
@@ -3383,5 +3244,23 @@ abstract class grade_helper {
}
return $result;
}
/**
* Resets all static caches.
*
* @return void
*/
public static function reset_caches() {
self::$managesetting = null;
self::$gradereports = null;
self::$gradereportpreferences = null;
self::$scaleinfo = null;
self::$outcomeinfo = null;
self::$letterinfo = null;
self::$importplugins = null;
self::$exportplugins = null;
self::$pluginstrings = null;
self::$aggregationstrings = null;
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die;
use \core_grades\output\action_bar;
/**
* Renderer class for the grade pages.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_grades_renderer extends plugin_renderer_base {
/**
* Renders the action bar for a given page.
*
* @param action_bar $actionbar
* @return string The HTML output
*/
public function render_action_bar(action_bar $actionbar): string {
$data = $actionbar->export_for_template($this);
return $this->render_from_template($actionbar->get_template(), $data);
}
}
+1 -8
View File
@@ -48,7 +48,7 @@ require('preferences_form.php');
$mform = new grader_report_preferences_form('preferences.php', compact('course'));
// If data submitted, then process and store.
if (!$mform->is_cancelled() && $data = $mform->get_data()) {
if ($data = $mform->get_data()) {
foreach ($data as $preference => $value) {
if (substr($preference, 0, 6) !== 'grade_') {
continue;
@@ -60,13 +60,6 @@ if (!$mform->is_cancelled() && $data = $mform->get_data()) {
set_user_preference($preference, $value);
}
}
redirect($CFG->wwwroot . '/grade/report/grader/index.php?id='.$courseid); // message here breaks accessability and is sloooowww
exit;
}
if ($mform->is_cancelled()){
redirect($CFG->wwwroot . '/grade/report/grader/index.php?id='.$courseid);
}
print_grade_page_head($courseid, 'settings', 'grader', get_string('preferences', 'gradereport_grader'));
+1 -1
View File
@@ -190,7 +190,7 @@ class grader_report_preferences_form extends moodleform {
$mform->setType('id', PARAM_INT);
$mform->setDefault('id', $course->id);
$this->add_action_buttons();
$this->add_action_buttons(false);
}
/// perform some extra moodle validation
+5 -1
View File
@@ -108,7 +108,11 @@ if ($table->is_downloading()) {
}
// Print header.
print_grade_page_head($COURSE->id, 'report', 'history', get_string('pluginname', 'gradereport_history'), false, '');
$actionbar = new \core_grades\output\general_action_bar($context,
new moodle_url('/grade/report/history/index.php', ['id' => $courseid]), 'report', 'history');
print_grade_page_head($COURSE->id, 'report', 'history', get_string('pluginname',
'gradereport_history'), false, false, true, null, null,
null, $actionbar);
$mform->display();
if ($showreport) {
@@ -53,7 +53,7 @@ Feature: A teacher checks the grade history report in a course
And I give the grade "70.00" to the user "Student 2" for the grade item "The greatest assignment ever"
And I give the grade "80.00" to the user "Student 2" for the grade item "Rewarding assignment"
And I press "Save changes"
And I follow "Grade history"
And I navigate to "View > Grade history" in the course gradebook
When I press "Submit"
Then the following should exist in the "gradereport_history" table:
| First name/Surname | Email address | Favourite food | Grade item | Original grade | Revised grade | Grader |
+9 -4
View File
@@ -90,6 +90,9 @@ $USER->grade_last_report[$course->id] = 'overview';
// First make sure we have proper final grades.
grade_regrade_final_grades_if_required($course);
$actionbar = new \core_grades\output\general_action_bar($context,
new moodle_url('/grade/report/overview/index.php', ['id' => $courseid]), 'report', 'overview');
if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
// Please note this would be extremely slow if we wanted to implement this properly for all teachers.
$groupmode = groups_get_course_groupmode($course); // Groups are being used
@@ -110,8 +113,8 @@ if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
}
if (empty($userid)) {
// Add tabs
print_grade_page_head($courseid, 'report', 'overview');
print_grade_page_head($courseid, 'report', 'overview', false, false, false,
true, null, null, null, $actionbar);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
@@ -124,7 +127,8 @@ if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
} else { // Only show one user's report
$report = new grade_report_overview($userid, $gpr, $context);
print_grade_page_head($courseid, 'report', 'overview', get_string('pluginname', 'gradereport_overview') .
' - ' . fullname($report->user), false, false, true, null, null, $report->user);
' - ' . fullname($report->user), false, false, true, null, null,
$report->user, $actionbar);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
if ($user_selector) {
@@ -170,7 +174,8 @@ if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
}
} else { // We have a course context. We must be navigating from the gradebook.
print_grade_page_head($courseid, 'report', 'overview', get_string('pluginname', 'gradereport_overview')
. ' - ' . fullname($report->user));
. ' - ' . fullname($report->user), false, false, true, null, null,
$report->user, $actionbar);
if ($report->fill_table()) {
echo '<br />' . $report->print_table(true);
}
+8 -2
View File
@@ -130,10 +130,16 @@ if ($data = data_submitted()) {
}
$PAGE->set_pagelayout('report');
$actionbar = new \core_grades\output\general_action_bar($context,
new moodle_url('/grade/report/singleview/index.php', ['id' => $courseid]), 'report', 'singleview');
if ($itemtype == 'user') {
print_grade_page_head($course->id, 'report', 'singleview', $reportname, false, false, true, null, null, $report->screen->item);
print_grade_page_head($course->id, 'report', 'singleview', $reportname, false, false,
true, null, null, $report->screen->item, $actionbar);
} else {
print_grade_page_head($course->id, 'report', 'singleview', $reportname);
print_grade_page_head($course->id, 'report', 'singleview', $reportname, false, false,
true, null, null, null, $actionbar);
}
$graderrightnav = $graderleftnav = null;
+1 -1
View File
@@ -138,7 +138,7 @@ if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all
$report = new grade_report_user($courseid, $gpr, $context, $user->id, $viewasuser);
$studentnamelink = html_writer::link(new moodle_url('/user/view.php', array('id' => $report->user->id, 'course' => $courseid)), fullname($report->user));
echo $OUTPUT->heading(get_string('pluginname', 'gradereport_user') . ' - ' . $studentnamelink);
echo $OUTPUT->heading($studentnamelink);
if ($report->fill_table()) {
echo '<br />'.$report->print_table(true);
@@ -0,0 +1,74 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/course_outcomes_action_bar
Actions bar for the gradebook course outcomes page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* manageoutcomesbutton - The data object containing the required properties to render the 'manage outcomes' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"manageoutcomesbutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Manage outcomes",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
{{#manageoutcomesbutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/manageoutcomesbutton}}
</div>
</div>
</div>
@@ -0,0 +1,82 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/export_action_bar
Actions bar for the gradebook export pages.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* exportselector - The data object containing the required properties to render the export options selector.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"exportselector": {
"id": "url_select56789",
"action": "https://example.com/get",
"formid": "gradesexportactionselect",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "OpenDocument spreadsheet",
"value": "/grade/export/ods/index.php",
"selected": true
}
],
"disabled": false,
"title": null
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
<div class="ml-2">
{{#exportselector}}
{{>core/url_select}}
{{/exportselector}}
</div>
</div>
</div>
</div>
@@ -0,0 +1,99 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/export_key_manager_action_bar
Actions bar for the gradebook exports key manager page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* exportselector - The data object containing the required properties to render the export options selector.
* adduserkeybutton - The data object containing the required properties to render the 'add user key' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"exportselector": {
"id": "url_select56789",
"action": "https://example.com/get",
"formid": "gradesexportactionselect",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "OpenDocument spreadsheet",
"value": "/grade/export/ods/index.php",
"selected": true
}
],
"disabled": false,
"title": null
},
"adduserkeybutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Add user key",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
<div class="ml-2">
{{#exportselector}}
{{>core/url_select}}
{{/exportselector}}
</div>
{{#adduserkeybutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/adduserkeybutton}}
</div>
</div>
</div>
@@ -0,0 +1,45 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/export_publish_action_bar
Actions bar for the gradebook publish export page.
Context variables required for this template:
* backbutton - The data object containing the required properties to render the 'back' button.
Example context (json):
{
"backbutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Back",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
{{#backbutton}}
{{>core/single_button}}
{{/backbutton}}
</div>
</div>
</div>
@@ -0,0 +1,55 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/general_action_bar
The general actions bar for navigating through the gradebook pages.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
</div>
</div>
@@ -0,0 +1,74 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/grade_letters_action_bar
Actions bar for the grade letters page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* editbutton - The data object containing the required properties to render the 'edit grade letters' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"editbutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Edit",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
{{#generalnavselector}}
<div class="mr-2">
{{>core/url_select}}
</div>
{{/generalnavselector}}
{{#editbutton}}
<div>
{{>core/single_button}}
</div>
{{/editbutton}}
</div>
</div>
</div>
@@ -0,0 +1,108 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/gradebook_setup_action_bar
Actions bar for the gradebook setup page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* addgradeitembutton - The data object containing the required properties to render the 'add grade item' button.
* addoutcomeitembutton - The data object containing the required properties to render the 'add outcome item' button.
* addcategorybutton - The data object containing the required properties to render the 'add category' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"addgradeitembutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Add grade item",
"attributes": []
},
"addoutcomeitembutton": {
"id": "single_button13245",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Add outcome item",
"attributes": []
},
"addcategorybutton": {
"id": "single_button14325",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Add category",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
{{#addgradeitembutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/addgradeitembutton}}
{{#addoutcomeitembutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/addoutcomeitembutton}}
{{#addcategorybutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/addcategorybutton}}
</div>
</div>
</div>
@@ -0,0 +1,82 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/import_action_bar
Actions bar for the gradebook import pages.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* importselector - The data object containing the required properties to render the import options selector.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"importselector": {
"id": "url_select56789",
"action": "https://example.com/get",
"formid": "gradesimportactionselect",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "CSV file",
"value": "/grade/import/csv/index.php",
"selected": true
}
],
"disabled": false,
"title": null
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
<div class="ml-2">
{{#importselector}}
{{>core/url_select}}
{{/importselector}}
</div>
</div>
</div>
</div>
@@ -0,0 +1,99 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/import_key_manager_action_bar
Actions bar for the gradebook imports key manager page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render core/url_select.
* importselector - The data object containing the required properties to render the import options selector.
* adduserkeybutton - The data object containing the required properties to render the 'add user key' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"importselector": {
"id": "url_select56789",
"action": "https://example.com/get",
"formid": "gradesimportactionselect",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "CSV file",
"value": "/grade/import/csv/index.php",
"selected": true
}
],
"disabled": false,
"title": null
},
"adduserkeybutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Add user key",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#generalnavselector}}
{{>core/url_select}}
{{/generalnavselector}}
</div>
<div class="ml-2">
{{#importselector}}
{{>core/url_select}}
{{/importselector}}
</div>
{{#adduserkeybutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/adduserkeybutton}}
</div>
</div>
</div>
@@ -0,0 +1,100 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/manage_outcomes_action_bar
Actions bar for the manage outcomes page.
Context variables required for this template:
* backbutton - The data object containing the required properties to render the 'back' button.
* addoutcomebutton - The data object containing the required properties to render the 'add a new outcome' button.
* importoutcomesbutton - The data object containing the required properties to render the 'import outcomes' button.
* exportoutcomesbutton - The data object containing the required properties to render the 'export outcomes' button.
Example context (json):
{
"backbutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Back",
"attributes": []
},
"addoutcomebutton": {
"id": "single_button13245",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Add a new outcome",
"attributes": []
},
"importoutcomesbutton": {
"id": "single_button14325",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Import outcomes",
"attributes": []
},
"exportoutcomesbutton": {
"id": "single_button15245",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : false,
"tooltip" : null,
"label" : "Export all outcomes",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
{{#backbutton}}
<div class="mr-2">
{{>core/single_button}}
</div>
{{/backbutton}}
{{#addoutcomebutton}}
<div>
{{>core/single_button}}
</div>
{{/addoutcomebutton}}
</div>
<div class="ml-auto d-flex">
{{#importoutcomesbutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/importoutcomesbutton}}
{{#exportoutcomesbutton}}
<div class="ml-2">
{{>core/single_button}}
</div>
{{/exportoutcomesbutton}}
</div>
</div>
</div>
@@ -0,0 +1,74 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_grades/scales_action_bar
Actions bar for the gradebook scales page.
Context variables required for this template:
* generalnavselector - The data object containing the required properties to render the general navigation selector.
* addnewscalebutton - The data object containing the required properties to render the 'add new scale' button.
Example context (json):
{
"generalnavselector": {
"id": "url_select12345",
"action": "https://example.com/get",
"classes": "urlselect",
"formid": "gradesactionselect",
"sesskey": "sesskey",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [{
"name": "View", "isgroup": true, "options":
[
{"name": "Grader report", "isgroup": false, "value": "/grade/report/grader/index.php"}
]},
{"name": "Setup", "isgroup": true, "options":
[
{"name": "Gradebook setup", "isgroup": false, "value": "/grade/edit/tree/index.php"}
]}],
"disabled": false,
"title": null
},
"addnewscalebutton": {
"id": "single_button12345",
"method" : "get",
"classes": "singlebutton",
"formid": null,
"url" : "#",
"primary" : true,
"tooltip" : null,
"label" : "Manage outcomes",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
{{#generalnavselector}}
<div class="mr-2">
{{>core/url_select}}
</div>
{{/generalnavselector}}
{{#addnewscalebutton}}
<div>
{{>core/single_button}}
</div>
{{/addnewscalebutton}}
</div>
</div>
</div>
+93 -6
View File
@@ -279,9 +279,13 @@ class behat_grade extends behat_base {
/**
* Select the tab in the gradebook. We must be on one of the gradebook pages already.
*
* @deprecated since 4.0 - use select_in_gradebook_navigation_selector() instead.
* @param string $gradepath examples: "View > User report", "Letters > View", "Scales"
*/
protected function select_in_gradebook_tabs($gradepath) {
debugging('The function select_in_gradebook_tabs() is deprecated, please use ' .
'select_in_gradebook_navigation_selector() instead.', DEBUG_DEVELOPER);
$gradepath = preg_split('/\s*>\s*/', trim($gradepath));
if (count($gradepath) > 2) {
throw new coding_exception('Grade path is too long (must have no more than two items separated with ">")');
@@ -309,17 +313,19 @@ class behat_grade extends behat_base {
}
/**
* Navigates to the course gradebook and selects a specified item from the grade navigation tabs.
* Navigates to the course gradebook and selects the specified item from the general grade navigation selector.
*
* Examples:
* - I navigate to "Setup > Gradebook setup" in the course gradebook
* - I navigate to "Scales" in the course gradebook
* - I navigate to "Letters > View" in the course gradebook
* - I navigate to "View > User report" in the course gradebook // for teachers
* - I navigate to "User report" in the course gradebook // for students
* - I navigate to "More > Grade letters" in the course gradebook
*
* @Given /^I navigate to "(?P<gradepath_string>(?:[^"]|\\")*)" in the course gradebook$/
* @param string $gradepath
* @param string $gradepath The path string. If the path has two items (ex. "More > Grade letters"), the first item
* ("More") will be used to identify an option group in the navigation selector, while the
* second ("Grade letters") will be used to identify an option within that option group.
* Otherwise, a single item in a path (ex. "Scales") will be used to identify an option in
* the navigation selector regardless of the option group.
*/
public function i_navigate_to_in_the_course_gradebook($gradepath) {
// If we are not on one of the gradebook pages already, follow "Grades" link in the navigation drawer.
@@ -328,6 +334,87 @@ class behat_grade extends behat_base {
$this->execute('behat_navigation::i_select_from_secondary_navigation', get_string('grades'));
}
$this->select_in_gradebook_tabs($gradepath);
$this->select_in_gradebook_navigation_selector($gradepath, 'gradesactionselect');
}
/**
* Navigates to the imports page in the course gradebook and selects the specified import type from the grade
* imports navigation selector.
*
* Examples:
* - I navigate to "CSV file" import page in the course gradebook
*
* @Given /^I navigate to "(?P<importoption_string>(?:[^"]|\\")*)" import page in the course gradebook$/
* @param string $gradeimportoption The name of an existing grade import option.
*/
public function i_navigate_to_import_page_in_the_course_gradebook($gradeimportoption) {
$this->i_navigate_to_in_the_course_gradebook("More > Import");
$this->select_in_gradebook_navigation_selector($gradeimportoption, 'gradesimportactionselect');
}
/**
* Navigates to the exports page in the course gradebook and selects the specified export type from the grade
* exports navigation selector.
*
* Examples:
* - I navigate to "XML file" export page in the course gradebook
*
* @Given /^I navigate to "(?P<exportoption_string>(?:[^"]|\\")*)" export page in the course gradebook$/
* @param string $gradeexportoption The name of an existing grade export option.
*/
public function i_navigate_to_export_page_in_the_course_gradebook($gradeexportoption) {
$this->i_navigate_to_in_the_course_gradebook("More > Export");
$this->select_in_gradebook_navigation_selector($gradeexportoption, 'gradesexportactionselect');
}
/**
* Select a given option from a navigation URL selector in the gradebook. We must be on one of the gradebook pages
* already.
*
* @param string $path The string path that is used to identify an item within the navigation selector. If the path
* has two items (ex. "More > Grade letters"), the first item ("More") will be used to identify
* an option group in the navigation selector, while the second ("Grade letters") will be used to
* identify an option within that option group. Otherwise, a single item in a path (ex. "Scales")
* will be used to identify an option in the navigation selector regardless of the option group.
* @param string $formid The ID of the form element which contains the navigation URL selector element.
*/
protected function select_in_gradebook_navigation_selector(string $path, string $formid) {
// Split the path string by ">".
$path = preg_split('/\s*>\s*/', trim($path));
// Make sure that the path does not have more than two items separated with ">".
if (count($path) > 2) {
throw new coding_exception('The path is too long (must have no more than two items separated with ">")');
}
// Get the select element.
$selectxpath = "//form[contains(@id,'{$formid}')]//select";
$select = $this->find('xpath', $selectxpath);
// Define the xpath to the option element depending on the provided path.
// If two items are provided in the path, the first item will be considered as an identifier of an existing
// option group in the select select element, while the second item will identify an existing option within
// that option group.
// If one item is provided in the path, this item will identify any existing option in the select element
// regardless of the option group. Also, this is useful when option elements are not a part of an option group
// which is possible.
if (count($path) === 2) {
$optionxpath = $selectxpath . '/optgroup[@label="' . $this->escape($path[0]) . '"]' .
'/option[contains(.,"' . $this->escape($path[1]) . '")]';
} else {
$optionxpath = $selectxpath . '//option[contains(.,"' . $this->escape($path[0]) . '")]';
}
// Get the option element that we are looking to select.
$option = $this->find('xpath', $optionxpath);
// Select the given option in the select element.
$field = behat_field_manager::get_field_instance('select', $select, $this->getSession());
$field->set_value($this->escape($option->getValue()));
if (!$this->running_javascript()) {
$this->execute('behat_general::i_click_on_in_the', [get_string('go'), 'button',
"#{$formid}", 'css_element']);
}
}
}
+12 -1
View File
@@ -65,6 +65,7 @@ Feature: We can use calculated grade totals
And I press "Save changes"
Scenario: Mean of grades aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Mean of grades |
And I set the following settings for grade item "Sub category 1":
@@ -83,6 +84,7 @@ Feature: We can use calculated grade totals
And I should see "30.42 (30.42 %)" in the "overview-grade" "table"
Scenario: Weighted mean of grades aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Weighted mean of grades |
And I set the following settings for grade item "Sub category 1":
@@ -105,6 +107,7 @@ Feature: We can use calculated grade totals
And I should see "26.94 (26.94 %)" in the "overview-grade" "table"
Scenario: Simple weighted mean of grades aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Simple weighted mean of grades |
And I set the following settings for grade item "Sub category 1":
@@ -125,6 +128,7 @@ Feature: We can use calculated grade totals
And I should see "48.57 (48.57 %)" in the "overview-grade" "table"
Scenario: Mean of grades (with extra credits) aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Mean of grades (with extra credits) |
And I set the following settings for grade item "Sub category 1":
@@ -145,6 +149,7 @@ Feature: We can use calculated grade totals
And I should see "47.22 (47.22 %)" in the "overview-grade" "table"
Scenario: Median of grades aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Median of grades |
And I set the following settings for grade item "Sub category 1":
@@ -163,6 +168,7 @@ Feature: We can use calculated grade totals
And I should see "25.83 (25.83 %)" in the "overview-grade" "table"
Scenario: Lowest grade aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Lowest grade |
And I set the following settings for grade item "Sub category 1":
@@ -185,6 +191,7 @@ Feature: We can use calculated grade totals
And I should see "0.00 (0.00 %)" in the "overview-grade" "table"
Scenario: Highest grade aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Highest grade |
And I set the following settings for grade item "Sub category 1":
@@ -205,6 +212,7 @@ Feature: We can use calculated grade totals
And I should see "50.00 (50.00 %)" in the "overview-grade" "table"
Scenario: Mode of grades aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Mode of grades |
And I set the following settings for grade item "Sub category 1":
@@ -315,6 +323,7 @@ Feature: We can use calculated grade totals
And "Test outcome item one" row "Grade" column of "user-grade" table should contain "Excellent (100.00 %)"
Scenario: Natural aggregation
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Sub category 1":
| Aggregation | Natural |
| Exclude empty grades | 0 |
@@ -502,7 +511,8 @@ Feature: We can use calculated grade totals
@javascript
Scenario: Natural aggregation with weights of zero
When I set the following settings for grade item "Course 1":
When I navigate to "View > Grader report" in the course gradebook
And I set the following settings for grade item "Course 1":
| Aggregation | Natural |
| Exclude empty grades | 0 |
And I set the following settings for grade item "Sub category 1":
@@ -528,6 +538,7 @@ Feature: We can use calculated grade totals
And I set the field "Show contribution to course total" to "Show"
And I set the field "Show weightings" to "Show"
And I press "Save changes"
And I navigate to "View > Grader report" in the course gradebook
Then I should see "75.00 (16.85 %)" in the ".course" "css_element"
And I navigate to "View > User report" in the course gradebook
And I select "Myself" from the "View report as" singleselect
@@ -31,6 +31,7 @@ Feature: Changing the aggregation of an item affects its weight and extra credit
| Item b3 | C1 | Cat natural & | 1 | 0.10 | 1 |
| Item b4 | C1 | Cat natural & | 1 | 0 | 0 |
And I log in as "admin"
And I change window size to "large"
And I set the following administration settings values:
| grade_aggregations_visible | Mean of grades,Weighted mean of grades,Simple weighted mean of grades,Mean of grades (with extra credits),Median of grades,Lowest grade,Highest grade,Mode of grades,Natural |
And I am on "Course 1" course homepage
@@ -26,8 +26,8 @@ Feature: We can customise the letter boundary of a course.
And I set the following fields to these values:
| Grade display type | Letter |
And I press "Save changes"
And I navigate to "Letters" in the course gradebook
And I follow "Edit grade letters"
And I navigate to "More > Grade letters" in the course gradebook
And I click on "Edit" "button"
And I set the following fields to these values:
| id_override | 1 |
| id_gradeboundary10 | 57 |
@@ -27,8 +27,8 @@ Feature: We can customise the letter boundary of a course in gradebook version 2
And I set the following fields to these values:
| Grade display type | Letter |
And I press "Save changes"
And I navigate to "Letters" in the course gradebook
And I follow "Edit grade letters"
And I navigate to "More > Grade letters" in the course gradebook
And I click on "Edit" "button"
And I set the following fields to these values:
| id_override | 1 |
| id_gradeboundary10 | 57 |
@@ -14,18 +14,18 @@ Feature: We can view the logs for any changes to grade letters.
And I set the following fields to these values:
| Grade display type | Letter |
And I press "Save changes"
And I navigate to "Letters" in the course gradebook
And I follow "Edit grade letters"
And I navigate to "More > Grade letters" in the course gradebook
And I click on "Edit" "button"
And I set the following fields to these values:
| id_override | 1 |
| id_gradeboundary10 | 57 |
And I press "Save changes"
And I follow "Edit grade letters"
And I click on "Edit" "button"
And I set the following fields to these values:
| id_override | 1 |
| id_gradeboundary10 | 50 |
And I press "Save changes"
And I follow "Edit grade letters"
And I click on "Edit" "button"
And I set the following fields to these values:
| id_override | 1 |
| id_gradeletter11 | |
@@ -2,7 +2,7 @@
Feature: Grade letters can be overridden
In order to test the grade letters functionality
As a teacher I override site defaults
and alter the grade letters
and alter the grade letters/edit/letter/index.php
Background:
Given the following "courses" exist:
@@ -16,7 +16,8 @@ Feature: Grade letters can be overridden
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Letters > Edit" in the course gradebook
And I navigate to "More > Grade letters" in the course gradebook
And I click on "Edit" "button"
Scenario Outline: Grade letters can be completely overridden
When I set the following fields to these values:
@@ -109,7 +110,7 @@ Feature: Grade letters can be overridden
| 49.99 % | 40.00 % | D |
| 39.99 % | 20.00 % | E |
| 19.99 % | 0.00 % | F |
When I follow "Edit grade letters"
When I click on "Edit" "button"
And I set the following fields to these values:
| override | 1 |
| Grade letter 1 | A |
@@ -176,7 +177,7 @@ Feature: Grade letters can be overridden
| 59.99 % | 50.00 % | C |
| 49.99 % | 40.00 % | D |
| 39.99 % | 0.00 % | F |
When I follow "Edit grade letters"
When I click on "Edit" "button"
And I set the following fields to these values:
| override | 1 |
| Grade letter 1 | α |
+2 -2
View File
@@ -70,8 +70,8 @@ Feature: We can enter in grades and view reports from the gradebook
Scenario: Grade a grade item and ensure the results display correctly in the gradebook
When I navigate to "View > User report" in the course gradebook
And "Grader report" "link" should exist
And "Outcomes report" "link" should exist
And the "jump" select box should contain "Grader report"
And the "jump" select box should contain "Outcomes report"
And the "Select all or one user" select box should contain "All users (1)"
And I log out
And I log in as "student1"
+230
View File
@@ -0,0 +1,230 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_grades\output;
use advanced_testcase;
use grade_helper;
use context_course;
use moodle_url;
/**
* A test class used to test general_action_bar.
*
* @package core_grades
* @copyright 2021 Mihail Geshoski <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class general_action_bar_test extends advanced_testcase {
/**
* Test the exported data for the general action bar for different user roles and settings.
*
* @dataProvider test_export_for_template_provider
* @param string $userrole The user role to test
* @param bool $enableoutcomes Whether to enable outcomes
* @param array $expectedoptions The expected options returned in the general action selector
*/
public function test_export_for_template_admin(string $userrole, bool $enableoutcomes, array $expectedoptions) {
global $PAGE;
$this->resetAfterTest();
// Reset the cache.
grade_helper::reset_caches();
// Create a course.
$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
if ($userrole === 'admin') {
$this->setAdminUser();
} else {
// Enrol user to the course.
$user = $this->getDataGenerator()->create_and_enrol($course, $userrole);
$this->setUser($user);
}
if ($enableoutcomes) {
set_config('enableoutcomes', 1);
}
$generalactionbar = new general_action_bar($coursecontext,
new moodle_url('/grade/report/user/index.php', ['id' => $course->id]), 'report', 'user');
$renderer = $PAGE->get_renderer('core');
$generalactionbardata = $generalactionbar->export_for_template($renderer);
$this->assertCount(1, $generalactionbardata);
$this->assertArrayHasKey('generalnavselector', $generalactionbardata);
$generalnavselector = $generalactionbardata['generalnavselector'];
// Assert the correct number of available option groups in the general navigation selector.
foreach ($generalnavselector->options as $option) {
if ($option['isgroup']) {
$groupname = $option['name'];
$groupoptions = $option['options'];
// Assert that the group name exists.
$this->assertArrayHasKey($groupname, $expectedoptions);
// Assert that the actual number of group options matches the number of expected options.
$this->assertEquals(count($expectedoptions[$groupname]), count($groupoptions));
foreach ($groupoptions as $option) {
$this->assertTrue(in_array($option['name'], $expectedoptions[$groupname]));
}
}
}
}
/**
* Data provider for the test_export_for_template test.
*
* @return array
*/
public function test_export_for_template_provider() : array {
return [
'Gradebook general navigation for admin; outcomes disabled.' => [
'admin',
false,
[
'View' => [
'Grader report',
'Grade history',
'Outcomes report',
'Overview report',
'Single view',
'User report',
],
'Setup' => [
'Gradebook setup',
'Course grade settings',
'Preferences: Grader report',
],
'More' => [
'Scales',
'Grade letters',
'Import',
'Export',
],
],
],
'Gradebook general navigation for admin; outcomes enabled.' => [
'admin',
true,
[
'View' => [
'Grader report',
'Grade history',
'Outcomes report',
'Overview report',
'Single view',
'User report',
],
'Setup' => [
'Gradebook setup',
'Course grade settings',
'Preferences: Grader report',
],
'More' => [
'Scales',
'Outcomes',
'Grade letters',
'Import',
'Export',
],
],
],
'Gradebook general navigation for editing teacher; outcomes disabled.' => [
'editingteacher',
false,
[
'View' => [
'Grader report',
'Grade history',
'Outcomes report',
'Overview report',
'Single view',
'User report',
],
'Setup' => [
'Gradebook setup',
'Course grade settings',
'Preferences: Grader report',
],
'More' => [
'Scales',
'Grade letters',
'Import',
'Export',
],
],
],
'Gradebook general navigation for editing teacher; outcomes enabled.' => [
'editingteacher',
true,
[
'View' => [
'Grader report',
'Grade history',
'Outcomes report',
'Overview report',
'Single view',
'User report',
],
'Setup' => [
'Gradebook setup',
'Course grade settings',
'Preferences: Grader report',
],
'More' => [
'Scales',
'Outcomes',
'Grade letters',
'Import',
'Export',
],
],
],
'Gradebook general navigation for non-editing teacher; outcomes enabled.' => [
'teacher',
true,
[
'View' => [
'Grader report',
'Grade history',
'Outcomes report',
'Overview report',
'User report',
],
'Setup' => [
'Preferences: Grader report',
],
'More' => [
'Export',
],
],
],
'Gradebook general navigation for student; outcomes enabled.' => [
'student',
true,
[
'View' => [
'Overview report',
'User report',
],
],
],
];
}
}
+9
View File
@@ -3,6 +3,15 @@ Information provided here is intended especially for developers.
=== 4.0 ===
* The select_in_gradebook_tabs() function in behat_grade.php has been deprecated. Please use the function
select_in_gradebook_navigation_selector() instead.
* The setting $CFG->grade_navmethod setting has been completely removed because it's not required anymore. This setting
was used to set the type of navigation (tabs or dropdown box) used in gradebook which is now replaced with tertiary
navigation.
* The print_grade_plugin_selector() function has been deprecated. This function was used to generate and output the
dropdown box navigation in gradebook which is now replaced with tertiary navigation.
* The grade_print_tabs() function has been deprecated. This function was used to generate and output the tabs navigation
in gradebook which is now replaced with tertiary navigation.
* There is a new callback inside of grade_get_plugin_info called extend_gradebook_plugininfo
which allows for new tabs to be added to the gradebook.
+4
View File
@@ -167,3 +167,7 @@ monthlyview,core_calendar
evidence,core_badges
recipientdetails,core_badges
recipientidentificationproblem,core_badges
navmethod,core_grades
dropdown,core_grades
tabs,core_grades
combo,core_grades
+9 -4
View File
@@ -120,7 +120,6 @@ $string['categorytotal'] = 'Category total';
$string['categorytotalname'] = 'Category total name';
$string['categorytotalfull'] = '{$a->category} total';
$string['collapsecriterion'] = 'Collapse criterion';
$string['combo'] = 'Tabs and drop-down menu';
$string['compact'] = 'Compact';
$string['componentcontrolsvisibility'] = 'Whether this grade item is hidden is controlled by the activity settings.';
$string['contract'] = 'Contract category';
@@ -155,7 +154,6 @@ $string['displaylettergrade'] = 'Display letter grades';
$string['displaypercent'] = 'Display percents';
$string['displaypoints'] = 'Display points';
$string['displayweighted'] = 'Display weighted grades';
$string['dropdown'] = 'Drop-down menu';
$string['droplow'] = 'Drop the lowest';
$string['droplow_help'] = 'This setting enables a specified number of the lowest grades to be excluded from the aggregation.';
$string['droplowestvalue'] = 'Set drop lowest grade value';
@@ -477,6 +475,7 @@ $string['locktimedate'] = 'Locked after: {$a}';
$string['lockverbose'] = 'Lock {$a->category} {$a->itemmodule} {$a->itemname}';
$string['lowest'] = 'Lowest';
$string['lowgradeletter'] = 'Low';
$string['manageoutcomes'] = 'Manage outcomes';
$string['manualitem'] = 'Manual item';
$string['mapfrom'] = 'Map from';
$string['mapfrom_help'] = 'Select the column in the spreadsheet containing data for identifying the user, such as username, user ID or email address.';
@@ -544,7 +543,6 @@ $string['mygrades_desc'] = 'This setting allows for the option of linking to an
$string['mypreferences'] = 'My preferences';
$string['myreportpreferences'] = 'My report preferences';
$string['mustchooserescaleyesorno'] = 'You must choose whether to rescale existing grades or not.';
$string['navmethod'] = 'Navigation method';
$string['neverdeletehistory'] = 'Never delete history';
$string['newcategory'] = 'New category';
$string['newitem'] = 'New grade item';
@@ -554,6 +552,8 @@ $string['nocategories'] = 'Grade categories could not be added or found for this
$string['nocategoryname'] = 'No category name was given.';
$string['nocategoryview'] = 'No category to view by';
$string['nocourses'] = 'There are no courses yet';
$string['noexistingscales'] = 'There are no existing scales.';
$string['noexistingoutcomes'] = 'There are no existing outcomes.';
$string['noforce'] = 'Do not force';
$string['nogradeletters'] = 'No grade letters set';
$string['nogradesreturned'] = 'No grades returned';
@@ -737,6 +737,7 @@ $string['setgradeletters'] = 'Set grade letters';
$string['setpreferences'] = 'Set preferences';
$string['setting'] = 'Setting';
$string['settings'] = 'Settings';
$string['setup'] = 'Setup';
$string['setweights'] = 'Set weights';
$string['showanalysisicon'] = 'Show grade analysis icon';
$string['showanalysisicon_desc'] = 'Whether to show grade analysis icon by default. If the activity module supports it, the grade analysis icon links to a page with more detailed explanation of the grade and how it was obtained.';
@@ -821,7 +822,6 @@ $string['aggregatesubcatsupgradedgrades'] = 'Note: The aggregation setting "Aggr
$string['upgradedgradeshidemessage'] = 'Dismiss notice';
$string['switchtofullview'] = 'Switch to full view';
$string['switchtosimpleview'] = 'Switch to simple view';
$string['tabs'] = 'Tabs';
$string['topcategory'] = 'Super category';
$string['total'] = 'Total';
$string['totalweightnot100'] = 'The total weight is not equal to 100';
@@ -888,3 +888,8 @@ $string['xml'] = 'XML';
$string['yes'] = 'Yes';
$string['yourgrade'] = 'Your grade';
// Deprecated since Moodle 4.0.
$string['navmethod'] = 'Navigation method';
$string['dropdown'] = 'Drop-down menu';
$string['tabs'] = 'Tabs';
$string['combo'] = 'Tabs and drop-down menu';
+1
View File
@@ -22,6 +22,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['adduserkey'] = 'Add user key';
$string['createnewkey'] = 'Create a new user key';
$string['createuserkey'] = 'Create user key';
$string['deletekeyconfirm'] = 'Do you really want to delete this user key?';
+10
View File
@@ -3189,5 +3189,15 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021120100.01);
}
if ($oldversion < 2021121400.01) {
// The $CFG->grade_navmethod setting has been removed because it's not required anymore. This setting was used
// to set the type of navigation (tabs or dropdown box) which will be displayed in gradebook. However, these
// navigation methods are no longer used and replaced with tertiary navigation.
unset_config('grade_navmethod');
// Main savepoint reached.
upgrade_main_savepoint(true, 2021121400.01);
}
return true;
}
+143
View File
@@ -3542,3 +3542,146 @@ function calendar_import_icalendar_events($ical, $unused = null, $subscriptionid
$return .= html_writer::end_tag('ul');
return $return;
}
/**
* Print grading plugin selection tab-based navigation.
*
* @deprecated since Moodle 4.0. Tabs navigation has been replaced with tertiary navigation.
* @param string $active_type type of plugin on current page - import, export, report or edit
* @param string $active_plugin active plugin type - grader, user, cvs, ...
* @param array $plugin_info Array of plugins
* @param boolean $return return as string
*
* @return nothing or string if $return true
*/
function grade_print_tabs($active_type, $active_plugin, $plugin_info, $return=false) {
global $CFG, $COURSE;
debugging('grade_print_tabs() has been deprecated. Tabs navigation has been replaced with tertiary navigation.',
DEBUG_DEVELOPER);
if (!isset($currenttab)) { //TODO: this is weird
$currenttab = '';
}
$tabs = array();
$top_row = array();
$bottom_row = array();
$inactive = array($active_plugin);
$activated = array($active_type);
$count = 0;
$active = '';
foreach ($plugin_info as $plugin_type => $plugins) {
if ($plugin_type == 'strings') {
continue;
}
// If $plugins is actually the definition of a child-less parent link:
if (!empty($plugins->id)) {
$string = $plugins->string;
if (!empty($plugin_info[$active_type]->parent)) {
$string = $plugin_info[$active_type]->parent->string;
}
$top_row[] = new tabobject($plugin_type, $plugins->link, $string);
continue;
}
$first_plugin = reset($plugins);
$url = $first_plugin->link;
if ($plugin_type == 'report') {
$url = $CFG->wwwroot.'/grade/report/index.php?id='.$COURSE->id;
}
$top_row[] = new tabobject($plugin_type, $url, $plugin_info['strings'][$plugin_type]);
if ($active_type == $plugin_type) {
foreach ($plugins as $plugin) {
$bottom_row[] = new tabobject($plugin->id, $plugin->link, $plugin->string);
if ($plugin->id == $active_plugin) {
$inactive = array($plugin->id);
}
}
}
}
// Do not display rows that contain only one item, they are not helpful.
if (count($top_row) > 1) {
$tabs[] = $top_row;
}
if (count($bottom_row) > 1) {
$tabs[] = $bottom_row;
}
if (empty($tabs)) {
return;
}
$rv = html_writer::div(print_tabs($tabs, $active_plugin, $inactive, $activated, true), 'grade-navigation');
if ($return) {
return $rv;
} else {
echo $rv;
}
}
/**
* Print grading plugin selection popup form.
*
* @deprecated since Moodle 4.0. Dropdown box navigation has been replaced with tertiary navigation.
* @param array $plugin_info An array of plugins containing information for the selector
* @param boolean $return return as string
*
* @return nothing or string if $return true
*/
function print_grade_plugin_selector($plugin_info, $active_type, $active_plugin, $return=false) {
global $CFG, $OUTPUT, $PAGE;
debugging('print_grade_plugin_selector() has been deprecated. Dropdown box navigation has been replaced ' .
'with tertiary navigation.', DEBUG_DEVELOPER);
$menu = array();
$count = 0;
$active = '';
foreach ($plugin_info as $plugin_type => $plugins) {
if ($plugin_type == 'strings') {
continue;
}
$first_plugin = reset($plugins);
$sectionname = $plugin_info['strings'][$plugin_type];
$section = array();
foreach ($plugins as $plugin) {
$link = $plugin->link->out(false);
$section[$link] = $plugin->string;
$count++;
if ($plugin_type === $active_type and $plugin->id === $active_plugin) {
$active = $link;
}
}
if ($section) {
$menu[] = array($sectionname=>$section);
}
}
// finally print/return the popup form
if ($count > 1) {
$select = new url_select($menu, $active, null, 'choosepluginreport');
$select->set_label(get_string('gradereport', 'grades'), array('class' => 'accesshide'));
if ($return) {
return $OUTPUT->render($select);
} else {
echo $OUTPUT->render($select);
}
} else {
// only one option - no plugin selector needed
return '';
}
}
-15
View File
@@ -239,21 +239,6 @@ define('GRADE_REPORT_MEAN_ALL', 0);
*/
define('GRADE_REPORT_MEAN_GRADED', 1);
/**
* GRADE_NAVMETHOD_DROPDOWN - Display a drop down box to allow navigation within the gradebook
*/
define('GRADE_NAVMETHOD_DROPDOWN', 0);
/**
* GRADE_NAVMETHOD_TABS - Display tabs to allow navigation within the gradebook
*/
define('GRADE_NAVMETHOD_TABS', 1);
/**
* GRADE_NAVMETHOD_TABS - Display both a drop down and tabs to allow navigation within the gradebook
*/
define('GRADE_NAVMETHOD_COMBO', 2);
/**
* GRADE_MIN_MAX_FROM_GRADE_ITEM - Get the grade min/max from the grade item.
*/
+2 -2
View File
@@ -55,7 +55,7 @@ Feature: In an assignment, teachers grade multiple students on one page
When I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Outcomes" in current page administration
And I follow "Edit outcomes"
And I press "Manage outcomes"
And I press "Add a new outcome"
And I follow "Add a new scale"
And I set the following fields to these values:
@@ -64,7 +64,7 @@ Feature: In an assignment, teachers grade multiple students on one page
And I press "Save changes"
And I am on "Course 1" course homepage
And I navigate to "Outcomes" in current page administration
And I follow "Edit outcomes"
And I press "Manage outcomes"
And I press "Add a new outcome"
And I set the following fields to these values:
| Full name | M8d skillZ! |
@@ -52,6 +52,6 @@ class behat_theme_classic_behat_grade extends behat_grade {
get_string('pluginname', 'block_navigation'), 'block'));
}
$this->select_in_gradebook_tabs($gradepath);
$this->select_in_gradebook_navigation_selector($gradepath, 'gradesactionselect');
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2021121400.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2021121400.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0dev+ (Build: 20211214)'; // Human-friendly version name