first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
<?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/>.
/**
* A moodleform for editing grade letters
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_letter_form extends moodleform {
public function definition() {
$mform =& $this->_form;
[
'lettercount' => $lettercount,
'admin' => $admin,
] = $this->_customdata;
$mform->addElement('header', 'gradeletters', get_string('gradeletters', 'grades'));
// Only show "override site defaults" checkbox if editing the course grade letters
if (!$admin) {
$mform->addElement('checkbox', 'override', get_string('overridesitedefaultgradedisplaytype', 'grades'));
$mform->addHelpButton('override', 'overridesitedefaultgradedisplaytype', 'grades');
}
$gradeletter = get_string('gradeletter', 'grades');
$gradeboundary = get_string('gradeboundary', 'grades');
// The fields to create the grade letter/boundary.
$elements = [];
$elements[] = $mform->createElement('text', 'gradeletter', "{$gradeletter} {no}");
$elements[] = $mform->createElement('static', '', '', '&ge;');
$elements[] = $mform->createElement('float', 'gradeboundary', "{$gradeboundary} {no}");
$elements[] = $mform->createElement('static', '', '', '%');
// Element options/rules, fields should be disabled unless "Override" is checked for course grade letters.
$options = [];
$options['gradeletter']['type'] = PARAM_TEXT;
if (!$admin) {
$options['gradeletter']['disabledif'] = ['override', 'notchecked'];
$options['gradeboundary']['disabledif'] = ['override', 'notchecked'];
}
// Create our repeatable elements, each one a group comprised of the fields defined previously.
$this->repeat_elements([
$mform->createElement('group', 'gradeentry', "{$gradeletter} {no}", $elements, [' '], false)
], $lettercount, $options, 'gradeentrycount', 'gradeentryadd', 3);
// Add a help icon to first element group, if it exists.
if ($mform->elementExists('gradeentry[0]')) {
$mform->addHelpButton('gradeentry[0]', 'gradeletter', 'grades');
}
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$this->add_action_buttons();
}
}
+265
View File
@@ -0,0 +1,265 @@
<?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/>.
/**
* List of grade letters.
*
* @package core_grades
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$contextid = optional_param('id', SYSCONTEXTID, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$edit = optional_param('edit', false, PARAM_BOOL); //are we editing?
$url = new moodle_url('/grade/edit/letter/index.php', array('id' => $contextid));
list($context, $course, $cm) = get_context_info_array($contextid);
$contextid = null;//now we have a context object throw away the $contextid from the params
//if viewing
if (!$edit) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:manageletters', $context)) {
throw new \moodle_exception('nopermissiontoviewletergrade');
}
} else {//else we're editing
require_capability('moodle/grade:manageletters', $context);
navigation_node::override_active_url($url);
$url->param('edit', 1);
$PAGE->navbar->add(get_string('editgradeletters', 'grades'), $url);
}
$PAGE->set_url($url);
$returnurl = null;
$editparam = null;
if ($context->contextlevel == CONTEXT_SYSTEM or $context->contextlevel == CONTEXT_COURSECAT) {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('letters');
$admin = true;
$returnurl = "$CFG->wwwroot/grade/edit/letter/index.php";
$editparam = '?edit=1';
$PAGE->set_primary_active_tab('siteadminnode');
} else if ($context->contextlevel == CONTEXT_COURSE) {
$PAGE->set_pagelayout('standard');//calling this here to make blocks display
require_login($context->instanceid, false, $cm);
$admin = false;
$returnurl = $CFG->wwwroot.'/grade/edit/letter/index.php?id='.$context->id;
$editparam = '&edit=1';
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'letter', 'courseid'=>$course->id));
} else {
throw new \moodle_exception('invalidcourselevel');
}
$strgrades = get_string('grades');
$pagename = get_string('letters', 'grades');
$letters = grade_get_letters($context);
$override = $DB->record_exists('grade_letters', array('contextid' => $context->id));
//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', false, false, false,
true, null, null, null, $actionbar);
}
$data = array();
$max = 100;
foreach($letters as $boundary=>$letter) {
$line = array();
$line[] = format_float($max,2).' %';
$line[] = format_float($boundary,2).' %';
$line[] = format_string($letter);
$data[] = $line;
$max = $boundary - 0.01;
}
if (!empty($override)) {
echo $OUTPUT->notification(get_string('gradeletteroverridden', 'grades'), 'notifymessage');
}
$table = new html_table();
$table->id = 'grade-letters-view';
$table->head = array(get_string('max', 'grades'), get_string('min', 'grades'), get_string('letter', 'grades'));
$table->size = array('30%', '30%', '40%');
$table->align = array('left', 'left', 'left');
$table->width = '30%';
$table->data = $data;
$table->tablealign = 'center';
echo html_writer::table($table);
} else { //else we're editing
require_once('edit_form.php');
$data = new stdClass();
$data->id = $context->id;
$i = 0;
foreach ($letters as $boundary=>$letter) {
$data->gradeletter[$i] = $letter;
$data->gradeboundary[$i] = $boundary;
$i++;
}
$data->override = $override;
// Count number of letters, used to build the repeated elements of the form.
$lettercount = count($letters);
$mform = new edit_letter_form($returnurl.$editparam, ['lettercount' => $lettercount, 'admin' => $admin]);
$mform->set_data($data);
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
// Make sure we are updating the cache.
$cache = cache::make('core', 'grade_letters');
if (!$admin and empty($data->override)) {
$records = $DB->get_records('grade_letters', array('contextid' => $context->id));
foreach ($records as $record) {
$DB->delete_records('grade_letters', array('id' => $record->id));
// Trigger the letter grade deleted event.
$event = \core\event\grade_letter_deleted::create(array(
'objectid' => $record->id,
'context' => $context,
));
$event->trigger();
}
// Make sure we clear the cache for this context.
$cache->delete($context->id);
redirect($returnurl);
}
$letters = array();
for ($i = 0; $i < $data->gradeentrycount; $i++) {
$letter = $data->gradeletter[$i];
if ($letter === '') {
continue;
}
$boundary = floatval($data->gradeboundary[$i]);
if ($boundary < 0 || $boundary > 100) {
continue; // Skip if out of range.
}
// The keys need to be strings so floats are not truncated.
$letters[number_format($boundary, 5)] = $letter;
}
$pool = array();
if ($records = $DB->get_records('grade_letters', array('contextid' => $context->id), 'lowerboundary ASC')) {
foreach ($records as $r) {
// Will re-use the lowerboundary to avoid duplicate during the update process.
$pool[number_format($r->lowerboundary, 5)] = $r;
}
}
foreach ($letters as $boundary => $letter) {
$record = new stdClass();
$record->letter = $letter;
$record->lowerboundary = $boundary;
$record->contextid = $context->id;
if (isset($pool[$boundary])) {
// Re-use the existing boundary to avoid key constraint.
if ($letter != $pool[$boundary]->letter) {
// The letter has been assigned to another boundary, we update it.
$record->id = $pool[$boundary]->id;
$DB->update_record('grade_letters', $record);
// Trigger the letter grade updated event.
$event = \core\event\grade_letter_updated::create(array(
'objectid' => $record->id,
'context' => $context,
));
$event->trigger();
}
unset($pool[$boundary]); // Remove the letter from the pool.
} else if ($candidate = array_pop($pool)) {
// The boundary is new, we update a random record from the pool.
$record->id = $candidate->id;
$DB->update_record('grade_letters', $record);
// Trigger the letter grade updated event.
$event = \core\event\grade_letter_updated::create(array(
'objectid' => $record->id,
'context' => $context,
));
$event->trigger();
} else {
// No records were found, this must be a new letter.
$newid = $DB->insert_record('grade_letters', $record);
// Trigger the letter grade added event.
$event = \core\event\grade_letter_created::create(array(
'objectid' => $newid,
'context' => $context,
));
$event->trigger();
}
}
// Cache the changed letters.
if (!empty($letters)) {
// For some reason, the cache saves it in the order in which they were entered
// but we really want to order them in descending order so we sort it here.
krsort($letters);
$cache->set($context->id, $letters);
}
// Delete the unused records.
foreach($pool as $leftover) {
$DB->delete_records('grade_letters', array('id' => $leftover->id));
// Trigger the letter grade deleted event.
$event = \core\event\grade_letter_deleted::create(array(
'objectid' => $leftover->id,
'context' => $context,
));
$event->trigger();
}
redirect($returnurl);
}
print_grade_page_head($COURSE->id, 'letter', 'edit', get_string('editgradeletters', 'grades'),
false, false, false);
$mform->display();
}
echo $OUTPUT->footer();
+43
View File
@@ -0,0 +1,43 @@
<?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/>.
/**
* Prints navigation tabs for viewing and editing grade letters
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$row = $tabs = array();
$row[] = new tabobject('lettersview',
$CFG->wwwroot.'/grade/edit/letter/index.php?id='.$COURSE->id,
get_string('letters', 'grades'));
if (has_capability('moodle/grade:manageletters', $context)) {
$row[] = new tabobject('lettersedit',
$CFG->wwwroot.'/grade/edit/letter/edit.php?id='.$context->id,
get_string('edit'));
}
$tabs[] = $row;
echo '<div class="letterdisplay">';
print_tabs($tabs, $currenttab);
echo '</div>';
+143
View File
@@ -0,0 +1,143 @@
<?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/>.
/**
* A page for selecting outcomes for use in a course
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$courseid = required_param('id', PARAM_INT);
$PAGE->set_url('/grade/edit/outcome/course.php', array('id'=>$courseid));
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
/// Make sure they can even access this course
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/course:update', $context);
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'outcomes', 'courseid'=>$courseid));
// first of all fix the state of outcomes_course table
$standardoutcomes = grade_outcome::fetch_all_global();
$co_custom = grade_outcome::fetch_all_local($courseid);
$co_standard_used = array();
$co_standard_notused = array();
if ($courseused = $DB->get_records('grade_outcomes_courses', array('courseid' => $courseid), '', 'outcomeid')) {
$courseused = array_keys($courseused);
} else {
$courseused = array();
}
// fix wrong entries in outcomes_courses
foreach ($courseused as $oid) {
if (!array_key_exists($oid, $standardoutcomes) and !array_key_exists($oid, $co_custom)) {
$DB->delete_records('grade_outcomes_courses', array('outcomeid' => $oid, 'courseid' => $courseid));
}
}
// fix local custom outcomes missing in outcomes_course
foreach($co_custom as $oid=>$outcome) {
if (!in_array($oid, $courseused)) {
$courseused[$oid] = $oid;
$goc = new stdClass();
$goc->courseid = $courseid;
$goc->outcomeid = $oid;
$DB->insert_record('grade_outcomes_courses', $goc);
}
}
// now check all used standard outcomes are in outcomes_course too
$params = array($courseid);
$sql = "SELECT DISTINCT outcomeid
FROM {grade_items}
WHERE courseid=? and outcomeid IS NOT NULL";
if ($realused = $DB->get_records_sql($sql, $params)) {
$realused = array_keys($realused);
foreach ($realused as $oid) {
if (array_key_exists($oid, $standardoutcomes)) {
$co_standard_used[$oid] = $standardoutcomes[$oid];
unset($standardoutcomes[$oid]);
if (!in_array($oid, $courseused)) {
$courseused[$oid] = $oid;
$goc = new stdClass();
$goc->courseid = $courseid;
$goc->outcomeid = $oid;
$DB->insert_record('grade_outcomes_courses', $goc);
}
}
}
}
// find all unused standard course outcomes - candidates for removal
foreach ($standardoutcomes as $oid=>$outcome) {
if (in_array($oid, $courseused)) {
$co_standard_notused[$oid] = $standardoutcomes[$oid];
unset($standardoutcomes[$oid]);
}
}
/// form processing
if ($data = data_submitted() and confirm_sesskey()) {
require_capability('moodle/grade:manageoutcomes', $context);
if (!empty($data->add) && !empty($data->addoutcomes)) {
/// add all selected to course list
foreach ($data->addoutcomes as $add) {
$add = clean_param($add, PARAM_INT);
if (!array_key_exists($add, $standardoutcomes)) {
continue;
}
$goc = new stdClass();
$goc->courseid = $courseid;
$goc->outcomeid = $add;
$DB->insert_record('grade_outcomes_courses', $goc);
}
} else if (!empty($data->remove) && !empty($data->removeoutcomes)) {
/// remove all selected from course outcomes list
foreach ($data->removeoutcomes as $remove) {
$remove = clean_param($remove, PARAM_INT);
if (!array_key_exists($remove, $co_standard_notused)) {
continue;
}
$DB->delete_records('grade_outcomes_courses', array('courseid' => $courseid, 'outcomeid' => $remove));
}
}
redirect('course.php?id='.$courseid); // we must redirect to get fresh data
}
$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');
echo $OUTPUT->footer();
+67
View File
@@ -0,0 +1,67 @@
<?php $maxlength=70; ?>
<form action="course.php" method="post">
<div>
<table class="courseoutcomes">
<tr>
<td>
<label for="removeoutcomes"><?php print_string('outcomescourse', 'grades'); ?></label>
<br />
<select id="removeoutcomes" size="20" name="removeoutcomes[]" multiple="multiple" class="form-control input-block-level">
<?php
if ($co_standard_notused) {
echo '<optgroup label="'.get_string('outcomescoursenotused', 'grades').'">';
foreach ($co_standard_notused as $outcome) {
echo '<option value="'.$outcome->id.'">'.shorten_text($outcome->get_name(), $maxlength).'</option>';
}
echo '</optgroup>';
}
if ($co_standard_used) {
echo '<optgroup label="'.get_string('outcomescourseused', 'grades').'">';
foreach ($co_standard_used as $outcome) {
echo '<option value="'.$outcome->id.'">'.shorten_text($outcome->get_name(), $maxlength).'</option>';
}
echo '</optgroup>';
}
if ($co_custom) {
echo '<optgroup label="'.get_string('outcomescoursecustom', 'grades').'">';
foreach ($co_custom as $outcome) {
echo '<option value="'.$outcome->id.'">'.shorten_text($outcome->get_name(), $maxlength).'</option>';
}
echo '</optgroup>';
}
?>
</select>
</td>
<?php
if (has_capability('moodle/grade:manageoutcomes', $context)) {
?>
<td class="pl-3 pr-3">
<div class="my-3">
<input name="add" class="btn btn-secondary" id="add" type="submit" value="<?php echo $OUTPUT->larrow() . ' ' .
get_string('add'); ?>" title="<?php print_string('add'); ?>" />
</div>
<div class="my-3">
<input name="remove" class="btn btn-secondary" id="remove" type="submit" value="<?php echo get_string('remove') .
' ' . $OUTPUT->rarrow(); ?>" title="<?php print_string('remove'); ?>" />
</div>
</td>
<?php } ?>
<td>
<label for="addoutcomes"><?php print_string('outcomesstandardavailable', 'grades'); ?></label>
<br />
<select id="addoutcomes" size="20" name="addoutcomes[]" multiple="multiple" class="form-control input-block-level">
<?php
foreach ($standardoutcomes as $outcome) {
echo '<option value="'.$outcome->id.'">'.shorten_text($outcome->get_name(), $maxlength).'</option>';
}
?>
</select>
</td>
</tr>
</table>
<input name="id" type="hidden" value="<?php echo $courseid?>"/>
<input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
</div>
</form>
+177
View File
@@ -0,0 +1,177 @@
<?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/>.
/**
* Edit page for grade outcomes.
*
* @package core_grades
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'edit_form.php';
$courseid = optional_param('courseid', 0, PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/outcome/edit.php');
if ($courseid !== 0) {
$url->param('courseid', $courseid);
}
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
$systemcontext = context_system::instance();
$heading = get_string('addoutcome', 'grades');
// a bit complex access control :-O
if ($id) {
$heading = get_string('editoutcome', 'grades');
/// editing existing outcome
if (!$outcome_rec = $DB->get_record('grade_outcomes', array('id' => $id))) {
throw new \moodle_exception('invalidoutcome');
}
if ($outcome_rec->courseid) {
$outcome_rec->standard = 0;
if (!$course = $DB->get_record('course', array('id' => $outcome_rec->courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$courseid = $course->id;
} else {
if ($courseid) {
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
}
$outcome_rec->standard = 1;
$outcome_rec->courseid = $courseid;
require_login();
require_capability('moodle/grade:manage', $systemcontext);
$PAGE->set_context($systemcontext);
}
} else if ($courseid){
/// adding new outcome from course
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$outcome_rec = new stdClass();
$outcome_rec->standard = 0;
$outcome_rec->courseid = $courseid;
} else {
require_login();
require_capability('moodle/grade:manage', $systemcontext);
$PAGE->set_context($systemcontext);
/// adding new outcome from admin section
$outcome_rec = new stdClass();
$outcome_rec->standard = 1;
$outcome_rec->courseid = 0;
}
if (!$courseid) {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
$PAGE->set_primary_active_tab('siteadminnode');
} else {
navigation_node::override_active_url(new moodle_url('/grade/edit/outcome/course.php', ['id' => $courseid]));
$PAGE->navbar->add(get_string('manageoutcomes', 'grades'),
new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]));
}
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$courseid);
$editoroptions = array(
'maxfiles' => EDITOR_UNLIMITED_FILES,
'maxbytes' => $CFG->maxbytes,
'trusttext' => false,
'noclean' => true,
'context' => $systemcontext
);
if (!empty($outcome_rec->id)) {
$editoroptions['subdirs'] = file_area_contains_subdirs($systemcontext, 'grade', 'outcome', $outcome_rec->id);
$outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $outcome_rec->id);
} else {
$editoroptions['subdirs'] = false;
$outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', null);
}
$mform = new edit_outcome_form(null, compact('gpr', 'editoroptions'));
$mform->set_data($outcome_rec);
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
$outcome = new grade_outcome(array('id'=>$id));
$data->usermodified = $USER->id;
if (empty($outcome->id)) {
$data->description = $data->description_editor['text'];
grade_outcome::set_properties($outcome, $data);
if (!has_capability('moodle/grade:manage', $systemcontext)) {
$data->standard = 0;
}
$outcome->courseid = !empty($data->standard) ? null : $courseid;
if (empty($outcome->courseid)) {
$outcome->courseid = null;
}
$outcome->insert();
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $outcome->id);
$DB->set_field($outcome->table, 'description', $data->description, array('id'=>$outcome->id));
} else {
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $id);
grade_outcome::set_properties($outcome, $data);
if (isset($data->standard)) {
$outcome->courseid = !empty($data->standard) ? null : $courseid;
} else {
unset($outcome->courseid); // keep previous
}
$outcome->update();
}
redirect($returnurl);
}
$PAGE->navbar->add($heading, $url);
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);
echo $OUTPUT->footer();
die();
}
$mform->display();
echo $OUTPUT->footer();
+160
View File
@@ -0,0 +1,160 @@
<?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/>.
/**
* Edit form for grade outcomes
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_outcome_form extends moodleform {
public function definition() {
global $CFG, $COURSE;
$mform =& $this->_form;
// visible elements
$mform->addElement('header', 'general', get_string('outcomes', 'grades'));
$mform->addElement('text', 'fullname', get_string('outcomefullname', 'grades'), 'size="40"');
$mform->addRule('fullname', get_string('required'), 'required');
$mform->setType('fullname', PARAM_TEXT);
$mform->addElement('text', 'shortname', get_string('outcomeshortname', 'grades'), 'size="20"');
$mform->addRule('shortname', get_string('required'), 'required');
$mform->setType('shortname', PARAM_NOTAGS);
$mform->addElement('advcheckbox', 'standard', get_string('outcomestandard', 'grades'));
$mform->addHelpButton('standard', 'outcomestandard', 'grades');
$options = array();
$mform->addElement('selectwithlink', 'scaleid', get_string('scale'), $options, null,
array('link' => $CFG->wwwroot.'/grade/edit/scale/edit.php?courseid='.$COURSE->id, 'label' => get_string('scalescustomcreate')));
$mform->addHelpButton('scaleid', 'typescale', 'grades');
$mform->addRule('scaleid', get_string('required'), 'required');
$mform->addElement('editor', 'description_editor', get_string('description'), null, $this->_customdata['editoroptions']);
// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG;
$mform =& $this->_form;
// first load proper scales
if ($courseid = $mform->getElementValue('courseid')) {
$options = array();
if ($scales = grade_scale::fetch_all_local($courseid)) {
$options[-1] = '--'.get_string('scalescustom');
foreach($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
if ($scales = grade_scale::fetch_all_global()) {
$options[-2] = '--'.get_string('scalesstandard');
foreach($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
$scale_el =& $mform->getElement('scaleid');
$scale_el->load($options);
} else {
$options = array();
if ($scales = grade_scale::fetch_all_global()) {
foreach($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
$scale_el =& $mform->getElement('scaleid');
$scale_el->load($options);
}
if ($id = $mform->getElementValue('id')) {
$outcome = grade_outcome::fetch(array('id'=>$id));
$itemcount = $outcome->get_item_uses_count();
$coursecount = $outcome->get_course_uses_count();
if ($itemcount) {
$mform->hardFreeze('scaleid');
}
if (empty($courseid)) {
$mform->hardFreeze('standard');
} else if (!has_capability('moodle/grade:manage', context_system::instance())) {
$mform->hardFreeze('standard');
} else if ($coursecount and empty($outcome->courseid)) {
$mform->hardFreeze('standard');
}
} else {
if (empty($courseid) or !has_capability('moodle/grade:manage', context_system::instance())) {
$mform->hardFreeze('standard');
}
}
}
/// perform extra validation before submission
function validation($data, $files) {
$errors = parent::validation($data, $files);
if ($data['scaleid'] < 1) {
$errors['scaleid'] = get_string('required');
}
if (!empty($data['standard']) and $scale = grade_scale::fetch(array('id'=>$data['scaleid']))) {
if (!empty($scale->courseid)) {
//TODO: localize
$errors['scaleid'] = 'Can not use custom scale in global outcome!';
}
}
return $errors;
}
}
+126
View File
@@ -0,0 +1,126 @@
<?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/>.
/**
* Exports selected outcomes in CSV format
*
* @package core_grades
* @copyright 2008 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$courseid = optional_param('id', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
/// Make sure they can even access this course
if ($courseid) {
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
if (empty($CFG->enableoutcomes)) {
redirect('../../index.php?id='.$courseid);
}
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
}
require_sesskey();
header("Content-Type: text/csv; charset=utf-8");
// TODO: make the filename more useful, include a date, a specific name, something...
header('Content-Disposition: attachment; filename=outcomes.csv');
// sending header with clear names, to make 'what is what' as easy as possible to understand
$header = array('outcome_name', 'outcome_shortname', 'outcome_description', 'scale_name', 'scale_items', 'scale_description');
echo format_csv($header, ';', '"');
$outcomes = array();
if ( $courseid ) {
$outcomes = array_merge(grade_outcome::fetch_all_global(), grade_outcome::fetch_all_local($courseid));
} else {
$outcomes = grade_outcome::fetch_all_global();
}
foreach($outcomes as $outcome) {
$line = array();
$line[] = $outcome->get_name();
$line[] = $outcome->get_shortname();
$line[] = $outcome->get_description();
$scale = $outcome->load_scale();
$line[] = $scale->get_name();
$line[] = $scale->compact_items();
$line[] = $scale->get_description();
echo format_csv($line, ';', '"');
}
/**
* Formats and returns a line of data, in CSV format. This code
* is from http://au2.php.net/manual/en/function.fputcsv.php#77866
*
* @param string[] $fields data to be exported
* @param string $delimiter char to be used to separate fields
* @param string $enclosure char used to enclose strings that contains newlines, spaces, tabs or the delimiter char itself
* @returns string one line of csv data
*/
function format_csv($fields = array(), $delimiter = ';', $enclosure = '"') {
$str = '';
$escape_char = '\\';
foreach ($fields as $value) {
if (strpos($value, $delimiter) !== false ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $value.$delimiter;
}
}
$str = substr($str,0,-1);
$str .= "\n";
return $str;
}
+259
View File
@@ -0,0 +1,259 @@
<?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/>.
/**
* Import outcomes from a file
*
* @package core_grades
* @copyright 2008 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__.'/../../../config.php');
require_once($CFG->dirroot.'/lib/formslib.php');
require_once($CFG->dirroot.'/grade/lib.php');
require_once($CFG->libdir.'/gradelib.php');
require_once('import_outcomes_form.php');
$courseid = optional_param('courseid', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$scope = optional_param('scope', 'custom', PARAM_ALPHA);
$url = new moodle_url('/grade/edit/outcome/import.php', array('courseid' => $courseid));
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
/// Make sure they can even access this course
if ($courseid) {
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
if (empty($CFG->enableoutcomes)) {
redirect('../../index.php?id='.$courseid);
}
navigation_node::override_active_url(new moodle_url('/grade/edit/outcome/course.php', ['id' => $courseid]));
$PAGE->navbar->add(get_string('manageoutcomes', 'grades'),
new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]));
$PAGE->navbar->add(get_string('importoutcomes', 'grades'),
new moodle_url('/grade/edit/outcome/import.php', ['courseid' => $courseid]));
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
$context = context_system::instance();
}
require_capability('moodle/grade:manageoutcomes', $context);
$upload_form = new import_outcomes_form();
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;
}
$imported_file = $CFG->tempdir . '/outcomeimport/importedfile_'.time().'.csv';
make_temp_directory('outcomeimport');
// copying imported file
if (!$upload_form->save_file('userfile', $imported_file, true)) {
redirect('import.php'. ($courseid ? "?courseid=$courseid" : ''), get_string('importfilemissing', 'grades'));
}
/// which scope are we importing the outcomes in?
if (isset($courseid) && ($scope == 'custom')) {
// custom scale
$local_scope = true;
} elseif (($scope == 'global') && has_capability('moodle/grade:manage', context_system::instance())) {
// global scale
$local_scope = false;
} else {
// shouldn't happen .. user might be trying to access this script without the right permissions.
redirect('index.php', get_string('importerror', 'grades'));
}
// open the file, start importing data
if ($handle = fopen($imported_file, 'r')) {
$line = 0; // will keep track of current line, to give better error messages.
$file_headers = '';
// $csv_data needs to have at least these columns, the value is the default position in the data file.
$headers = array('outcome_name' => 0, 'outcome_shortname' => 1, 'scale_name' => 3, 'scale_items' => 4);
$optional_headers = array('outcome_description'=>2, 'scale_description' => 5);
$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.
while ( $csv_data = fgetcsv($handle, 8192, ';', '"')) { // if the line is over 8k, it won't work...
$line++;
// be tolerant on input, as fgetcsv returns "an array comprising a single null field" on blank lines
if ($csv_data == array(null)) {
continue;
}
// on first run, grab and analyse the header
if ($file_headers == '') {
$file_headers = array_flip($csv_data); // save the header line ... TODO: use the header line to let import work with columns in arbitrary order
$error = false;
foreach($headers as $key => $value) {
// sanity check #1: make sure the file contains all the mandatory headers
if (!array_key_exists($key, $file_headers)) {
$error = true;
break;
}
}
if ($error) {
$fatal_error = true;
$errormessage = get_string('importoutcomenofile', 'grades', $line);
break;
}
foreach(array_merge($headers, $optional_headers) as $header => $position) {
// match given columns to expected columns *into* $headers
$imported_headers[$header] = $file_headers[$header];
}
continue; // we don't import headers
}
// 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) ) {
$fatal_error = 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]] == '') {
$fatal_error = true;
$errormessage = get_string('importoutcomenofile', 'grades', $line);
break;
}
}
// MDL-17273 errors in csv are not preventing import from happening. We break from the while loop here
if ($fatal_error) {
break;
}
$params = array($csv_data[$imported_headers['outcome_shortname']]);
$wheresql = 'shortname = ? ';
if ($local_scope) {
$params[] = $courseid;
$wheresql .= ' AND courseid = ?';
} else {
$wheresql .= ' AND courseid IS NULL';
}
$outcome = $DB->get_records_select('grade_outcomes', $wheresql, $params);
if ($outcome) {
// already exists, print a message and skip.
echo $OUTPUT->notification(get_string('importskippedoutcome', 'grades',
$csv_data[$imported_headers['outcome_shortname']]), 'info', false);
continue;
}
// new outcome will be added, search for compatible existing scale...
$params = array($csv_data[$imported_headers['scale_name']], $csv_data[$imported_headers['scale_items']], $courseid);
$wheresql = 'name = ? AND scale = ? AND (courseid = ? OR courseid = 0)';
$scale = $DB->get_records_select('scale', $wheresql, $params);
if ($scale) {
// already exists in the right scope: use it.
$scale_id = key($scale);
} else {
if (!has_capability('moodle/course:managescales', $context)) {
echo $OUTPUT->notification(get_string('importskippedoutcome', 'grades',
$csv_data[$imported_headers['outcome_shortname']]), 'warning', false);
continue;
} else {
// scale doesn't exists : create it.
$scale_data = array('name' => $csv_data[$imported_headers['scale_name']],
'scale' => $csv_data[$imported_headers['scale_items']],
'description' => $csv_data[$imported_headers['scale_description']],
'userid' => $USER->id);
if ($local_scope) {
$scale_data['courseid'] = $courseid;
} else {
$scale_data['courseid'] = 0; // 'global' : scale use '0', outcomes use null
}
$scale = new grade_scale($scale_data);
$scale_id = $scale->insert();
}
}
// add outcome
$outcome_data = array('shortname' => $csv_data[$imported_headers['outcome_shortname']],
'fullname' => $csv_data[$imported_headers['outcome_name']],
'scaleid' => $scale_id,
'description' => $csv_data[$imported_headers['outcome_description']],
'usermodified' => $USER->id);
if ($local_scope) {
$outcome_data['courseid'] = $courseid;
} else {
$outcome_data['courseid'] = null; // 'global' : scale use '0', outcomes use null
}
$outcome = new grade_outcome($outcome_data);
$outcome_id = $outcome->insert();
$outcome_success_strings = new StdClass();
$outcome_success_strings->name = $outcome_data['fullname'];
$outcome_success_strings->id = $outcome_id;
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));
}
// finish
fclose($handle);
// delete temp file
unlink($imported_file);
echo $OUTPUT->footer();
@@ -0,0 +1,62 @@
<?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/>.
/**
* A form to allow importing outcomes from a file
*
* @package core_grades
* @copyright 2008 Moodle Pty Ltd (http://moodle.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once($CFG->dirroot.'/lib/formslib.php');
class import_outcomes_form extends moodleform {
public function definition() {
global $PAGE, $USER;
$mform =& $this->_form;
$mform->addElement('hidden', 'action', 'upload');
$mform->setType('action', PARAM_ALPHANUMEXT);
$mform->addElement('hidden', 'courseid', $PAGE->course->id);
$mform->setType('courseid', PARAM_INT);
$scope = array();
if (($PAGE->course->id > 1) && has_capability('moodle/grade:manage', context_system::instance())) {
$mform->addElement('radio', 'scope', get_string('importcustom', 'grades'), null, 'custom');
$mform->addElement('radio', 'scope', get_string('importstandard', 'grades'), null, 'global');
$mform->setDefault('scope', 'custom');
}
$mform->addElement('filepicker', 'userfile', get_string('importoutcomes', 'grades'));
$mform->addRule('userfile', get_string('required'), 'required', null, 'server');
$mform->addHelpButton('userfile', 'importoutcomes', 'grades');
$buttonarray = [
$mform->createElement('submit', 'save', get_string('uploadthisfile')),
$mform->createElement('cancel')
];
$mform->addGroup($buttonarray, 'buttonar', '', ' ', false);
}
}
+257
View File
@@ -0,0 +1,257 @@
<?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/>.
/**
* Listing page for grade outcomes.
*
* @package core_grades
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__.'/../../../config.php');
require_once($CFG->dirroot.'/grade/lib.php');
require_once($CFG->libdir.'/gradelib.php');
$courseid = optional_param('id', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$url = new moodle_url('/grade/edit/outcome/index.php', ['id' => $courseid]);
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
/// Make sure they can even access this course
if ($courseid) {
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manageoutcomes', $context);
if (empty($CFG->enableoutcomes)) {
redirect('../../index.php?id='.$courseid);
}
// This page doesn't exist on the navigation so map it to another
navigation_node::override_active_url(new moodle_url('/grade/edit/outcome/course.php', array('id'=>$courseid)));
$PAGE->navbar->add(get_string('manageoutcomes', 'grades'), $url);
} else {
if (empty($CFG->enableoutcomes)) {
redirect('../../../');
}
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('outcomes');
$context = context_system::instance();
$PAGE->set_primary_active_tab('siteadminnode');
}
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'outcome', 'courseid'=>$courseid));
$strshortname = get_string('outcomeshortname', 'grades');
$strfullname = get_string('outcomefullname', 'grades');
$strscale = get_string('scale');
$strstandardoutcome = get_string('outcomesstandard', 'grades');
$strcustomoutcomes = get_string('outcomescustom', 'grades');
$strcreatenewoutcome = get_string('outcomecreate', 'grades');
$stritems = get_string('items', 'grades');
$strcourses = get_string('courses');
$stredit = get_string('edit');
switch ($action) {
case 'delete':
if (!confirm_sesskey()) {
break;
}
$outcomeid = required_param('outcomeid', PARAM_INT);
if (!$outcome = grade_outcome::fetch(array('id'=>$outcomeid))) {
break;
}
if (empty($outcome->courseid)) {
require_capability('moodle/grade:manage', context_system::instance());
} else if ($outcome->courseid != $courseid) {
throw new \moodle_exception('invalidcourseid');
}
if (!$outcome->can_delete()) {
break;
}
$deleteconfirmed = optional_param('deleteconfirmed', 0, PARAM_BOOL);
if(!$deleteconfirmed){
$PAGE->set_title(get_string('outcomedelete', 'grades'));
$PAGE->navbar->add(get_string('outcomedelete', 'grades'));
echo $OUTPUT->header();
$confirmurl = new moodle_url('index.php', array(
'id' => $courseid, 'outcomeid' => $outcome->id,
'action'=> 'delete',
'sesskey' => sesskey(),
'deleteconfirmed'=> 1));
echo $OUTPUT->confirm(get_string('outcomeconfirmdelete', 'grades', $outcome->fullname), $confirmurl, "index.php?id={$courseid}");
echo $OUTPUT->footer();
die;
}else{
$outcome->delete();
}
break;
}
$systemcontext = context_system::instance();
$caneditsystemscales = has_capability('moodle/course:managescales', $systemcontext);
if ($courseid) {
$caneditcoursescales = has_capability('moodle/course:managescales', $context);
} else {
$caneditcoursescales = $caneditsystemscales;
}
$outcomes_tables = array();
$heading = get_string('outcomes', 'grades');
if ($courseid and $outcomes = grade_outcome::fetch_all_local($courseid)) {
$return = $OUTPUT->heading($strcustomoutcomes, 3, 'main mt-3');
$data = array();
foreach($outcomes as $outcome) {
$line = array();
$line[] = $outcome->get_name();
$line[] = $outcome->get_shortname();
$scale = $outcome->load_scale();
if (empty($scale->id)) { // hopefully never happens
$line[] = $scale->get_name();
debugging("Found a scale with no ID ({$scale->get_name()}) while outputting course outcomes", DEBUG_DEVELOPER);
} else {
if (empty($scale->courseid)) {
$caneditthisscale = $caneditsystemscales;
} else if ($scale->courseid == $courseid) {
$caneditthisscale = $caneditcoursescales;
} else {
$context = context_course::instance($scale->courseid);
$caneditthisscale = has_capability('moodle/course:managescales', $context);
}
if ($caneditthisscale) {
$line[] = grade_print_scale_link($courseid, $scale, $gpr);
} else {
$line[] = $scale->get_name();
}
}
$line[] = $outcome->get_item_uses_count();
$buttons = grade_button('edit', $courseid, $outcome);
if ($outcome->can_delete()) {
$buttons .= grade_button('delete', $courseid, $outcome);
}
$line[] = $buttons;
$data[] = $line;
}
$table = new html_table();
$table->head = array($strfullname, $strshortname, $strscale, $stritems, $stredit);
$table->size = array('30%', '20%', '20%', '20%', '10%' );
$table->align = array('left', 'left', 'left', 'center', 'center');
$table->width = '90%';
$table->data = $data;
$return .= html_writer::table($table);
$outcomes_tables[] = $return;
}
if ($outcomes = grade_outcome::fetch_all_global()) {
$return = $OUTPUT->heading($strstandardoutcome, 3, 'main mt-3');
$data = array();
foreach($outcomes as $outcome) {
$line = array();
$line[] = $outcome->get_name();
$line[] = $outcome->get_shortname();
$scale = $outcome->load_scale();
if (empty($scale->id)) { // hopefully never happens
$line[] = $scale->get_name();
debugging("Found a scale with no ID ({$scale->get_name()}) while outputting global outcomes", DEBUG_DEVELOPER);
} else {
if (empty($scale->courseid)) {
$caneditthisscale = $caneditsystemscales;
} else if ($scale->courseid == $courseid) {
$caneditthisscale = $caneditcoursescales;
} else {
$context = context_course::instance($scale->courseid);
$caneditthisscale = has_capability('moodle/course:managescales', $context);
}
if ($caneditthisscale) {
$line[] = grade_print_scale_link($courseid, $scale, $gpr);
} else {
$line[] = $scale->get_name();
}
}
$line[] = $outcome->get_course_uses_count();
$line[] = $outcome->get_item_uses_count();
$buttons = "";
if (has_capability('moodle/grade:manage', context_system::instance())) {
$buttons .= grade_button('edit', $courseid, $outcome);
}
if (has_capability('moodle/grade:manage', context_system::instance()) and $outcome->can_delete()) {
$buttons .= grade_button('delete', $courseid, $outcome);
}
$line[] = $buttons;
$data[] = $line;
}
$table = new html_table();
$table->head = array($strfullname, $strshortname, $strscale, $strcourses, $stritems, $stredit);
$table->size = array('30%', '20%', '20%', '10%', '10%', '10%');
$table->align = array('left', 'left', 'left', 'center', 'center', 'center');
$table->width = '90%';
$table->data = $data;
$return .= html_writer::table($table);
$outcomes_tables[] = $return;
}
$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);
// 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->footer();
/**
* Local shortcut function for creating a link to a scale.
* @param int $courseid The Course ID
* @param grade_scale $scale The Scale to link to
* @param grade_plugin_return $gpr An object used to identify the page we just came from
* @return string html
*/
function grade_print_scale_link($courseid, $scale, $gpr) {
global $CFG, $OUTPUT;
$url = new moodle_url('/grade/edit/scale/edit.php', array('courseid' => $courseid, 'id' => $scale->id));
$url = $gpr->add_url_params($url);
return html_writer::link($url, $scale->get_name());
}
+45
View File
@@ -0,0 +1,45 @@
<?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/>.
/**
* Prints navigation tabs for viewing and editing grade outcomes
*
* @package core_grades
* @copyright 2009 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$row = $tabs = array();
$context = context_course::instance($courseid);
$row[] = new tabobject('courseoutcomes',
$CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$courseid,
get_string('outcomescourse', 'grades'));
if (has_capability('moodle/grade:manage', $context)) {
$row[] = new tabobject('outcomes',
$CFG->wwwroot.'/grade/edit/outcome/index.php?id='.$courseid,
get_string('editoutcomes', 'grades'));
}
$tabs[] = $row;
echo '<div class="outcomedisplay">';
print_tabs($tabs, $currenttab);
echo '</div>';
+153
View File
@@ -0,0 +1,153 @@
<?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/>.
/**
* Edit page for grade scales
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'edit_form.php';
$courseid = optional_param('courseid', 0, PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$PAGE->set_url('/grade/edit/scale/edit.php', array('id' => $id, 'courseid' => $courseid));
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/scale/index.php',
array('id' => $courseid)));
$systemcontext = context_system::instance();
// a bit complex access control :-O
if ($id) {
/// editing existing scale
if (!$scale_rec = $DB->get_record('scale', array('id' => $id))) {
throw new \moodle_exception('invalidscaleid');
}
if ($scale_rec->courseid) {
$scale_rec->standard = 0;
if (!$course = $DB->get_record('course', array('id' => $scale_rec->courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/course:managescales', $context);
$courseid = $course->id;
} else {
if ($courseid) {
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
}
$scale_rec->standard = 1;
$scale_rec->courseid = $courseid;
require_login($courseid);
require_capability('moodle/course:managescales', $systemcontext);
}
} else if ($courseid){
/// adding new scale from course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
$scale_rec = new stdClass();
$scale_rec->standard = 0;
$scale_rec->courseid = $courseid;
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/course:managescales', $context);
} else {
/// adding new scale from admin section
$scale_rec = new stdClass();
$scale_rec->standard = 1;
$scale_rec->courseid = 0;
require_login();
require_capability('moodle/course:managescales', $systemcontext);
}
if (!$courseid) {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('scales');
$PAGE->set_primary_active_tab('siteadminnode');
}
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$courseid);
$editoroptions = array(
'maxfiles' => EDITOR_UNLIMITED_FILES,
'maxbytes' => $CFG->maxbytes,
'trusttext' => false,
'noclean' => true,
'context' => $systemcontext
);
if (!empty($scale_rec->id)) {
$editoroptions['subdirs'] = file_area_contains_subdirs($systemcontext, 'grade', 'scale', $scale_rec->id);
$scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $scale_rec->id);
} else {
$editoroptions['subdirs'] = false;
$scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade', 'scale', null);
}
$mform = new edit_scale_form(null, compact('gpr', 'editoroptions'));
$mform->set_data($scale_rec);
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
$scale = new grade_scale(array('id'=>$id));
$data->userid = $USER->id;
if (empty($scale->id)) {
$data->description = $data->description_editor['text'];
$data->descriptionformat = $data->description_editor['format'];
grade_scale::set_properties($scale, $data);
if (!has_capability('moodle/grade:manage', $systemcontext)) {
$data->standard = 0;
}
$scale->courseid = !empty($data->standard) ? 0 : $courseid;
$scale->insert();
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $scale->id);
$DB->set_field($scale->table, 'description', $data->description, array('id'=>$scale->id));
} else {
$data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $id);
grade_scale::set_properties($scale, $data);
if (isset($data->standard)) {
$scale->courseid = !empty($data->standard) ? 0 : $courseid;
} else {
unset($scale->courseid); // keep previous
}
$scale->update();
}
redirect($returnurl);
}
$heading = $id ? get_string('editscale', 'grades') : get_string('addscale', 'grades');
$PAGE->navbar->add($heading);
print_grade_page_head($COURSE->id, 'scale', null, $heading, false, false, false);
$mform->display();
echo $OUTPUT->footer();
+164
View File
@@ -0,0 +1,164 @@
<?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/>.
/**
* Edit form for grade scales
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_scale_form extends moodleform {
function definition() {
global $CFG;
$mform =& $this->_form;
// visible elements
$mform->addElement('header', 'general', get_string('scale'));
$mform->addElement('text', 'name', get_string('name'), 'size="40"');
$mform->addRule('name', get_string('required'), 'required', null, 'client');
$mform->setType('name', PARAM_TEXT);
$mform->addElement('advcheckbox', 'standard', get_string('scalestandard'));
$mform->addHelpButton('standard', 'scalestandard');
$mform->addElement('static', 'used', get_string('used'));
$mform->addElement('textarea', 'scale', get_string('scale'), array('cols'=>50, 'rows'=>2));
$mform->addHelpButton('scale', 'scale');
$mform->addRule('scale', get_string('required'), 'required', null, 'client');
$mform->setType('scale', PARAM_TEXT);
$mform->addElement('editor', 'description_editor', get_string('description'), null, $this->_customdata['editoroptions']);
// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG;
$mform =& $this->_form;
$courseid = $mform->getElementValue('courseid');
if ($id = $mform->getElementValue('id')) {
$scale = grade_scale::fetch(array('id'=>$id));
$used = $scale->is_used();
if ($used) {
$mform->hardFreeze('scale');
}
if (empty($courseid)) {
$mform->hardFreeze('standard');
} else if (!has_capability('moodle/course:managescales', context_system::instance())) {
//if they dont have managescales at system level the shouldnt be allowed to make scales standard (or not standard)
$mform->hardFreeze('standard');
} else if ($used and !empty($scale->courseid)) {
$mform->hardFreeze('standard');
}
$usedstr = $scale->is_used() ? get_string('yes') : get_string('no');
$used_el =& $mform->getElement('used');
$used_el->setValue($usedstr);
} else {
$mform->removeElement('used');
if (empty($courseid) or !has_capability('moodle/course:managescales', context_system::instance())) {
$mform->hardFreeze('standard');
}
}
}
/// perform extra validation before submission
function validation($data, $files) {
global $CFG, $COURSE, $DB;
$errors = parent::validation($data, $files);
// we can not allow 2 scales with the same exact scale as this creates
// problems for backup/restore
$old = grade_scale::fetch(array('id'=>$data['id']));
if (array_key_exists('standard', $data)) {
if (empty($data['standard'])) {
$courseid = $COURSE->id;
} else {
$courseid = 0;
}
} else {
$courseid = $old->courseid;
}
if (array_key_exists('scale', $data)) {
$scalearray = explode(',', $data['scale']);
$scalearray = array_map('trim', $scalearray);
$scaleoptioncount = count($scalearray);
if (count($scalearray) < 1) {
$errors['scale'] = get_string('badlyformattedscale', 'grades');
} else {
$thescale = implode(',',$scalearray);
//this check strips out whitespace from the scale we're validating but not from those already in the DB
$count = $DB->count_records_select('scale', "courseid=:courseid AND ".$DB->sql_compare_text('scale', core_text::strlen($thescale)).'=:scale',
array('courseid'=>$courseid, 'scale'=>$thescale));
if ($count) {
//if this is a new scale but we found a duplice in the DB
//or we found a duplicate in another course report the error
if (empty($old->id) or $old->courseid != $courseid) {
$errors['scale'] = get_string('duplicatescale', 'grades');
} else if ($old->scale !== $thescale and $old->scale !== $data['scale']) {
//if the old scale from DB is different but we found a duplicate then we're trying to modify a scale to be a duplicate
$errors['scale'] = get_string('duplicatescale', 'grades');
}
}
}
}
return $errors;
}
}
+200
View File
@@ -0,0 +1,200 @@
<?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/>.
/**
* A page for managing custom and standard scales
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
$courseid = optional_param('id', 0, PARAM_INT);
$action = optional_param('action', '', PARAM_ALPHA);
$PAGE->set_url('/grade/edit/scale/index.php', array('id' => $courseid));
/// Make sure they can even access this course
if ($courseid) {
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/course:managescales', $context);
$PAGE->set_pagelayout('admin');
} else {
require_once $CFG->libdir.'/adminlib.php';
admin_externalpage_setup('scales');
$context = context_system::instance();
$PAGE->set_primary_active_tab('siteadminnode');
}
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'scale', 'courseid'=>$courseid));
$strscale = get_string('scale');
$strstandardscale = get_string('scalesstandard');
$strcustomscales = get_string('scalescustom');
$strname = get_string('name');
$strdelete = get_string('delete');
$stredit = get_string('edit');
$strused = get_string('used');
$stredit = get_string('edit');
switch ($action) {
case 'delete':
if (!confirm_sesskey()) {
break;
}
$scaleid = required_param('scaleid', PARAM_INT);
if (!$scale = grade_scale::fetch(array('id'=>$scaleid))) {
break;
}
if (empty($scale->courseid)) {
require_capability('moodle/course:managescales', context_system::instance());
} else if ($scale->courseid != $courseid) {
throw new \moodle_exception('invalidcourseid');
}
if (!$scale->can_delete()) {
break;
}
$deleteconfirmed = optional_param('deleteconfirmed', 0, PARAM_BOOL);
if (!$deleteconfirmed) {
if ($courseid) {
$PAGE->navbar->add(get_string('scales'), new moodle_url('/grade/edit/scale/index.php',
['id' => $courseid]));
}
$strdeletescale = get_string('deletescale', 'grades');
$PAGE->navbar->add($strdeletescale);
$PAGE->set_title($strdeletescale);
$PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
$confirmurl = new moodle_url('index.php', array(
'id' => $courseid, 'scaleid' => $scale->id,
'action'=> 'delete',
'sesskey' => sesskey(),
'deleteconfirmed'=> 1));
echo $OUTPUT->confirm(get_string('scaleconfirmdelete', 'grades', $scale->get_name()), $confirmurl,
"index.php?id={$courseid}");
echo $OUTPUT->footer();
die;
} else {
$scale->delete();
}
break;
}
if (!$courseid) {
echo $OUTPUT->header();
}
$table = new html_table();
$table2 = new html_table();
$heading = '';
if ($courseid and $scales = grade_scale::fetch_all_local($courseid)) {
$heading = $strcustomscales;
$data = array();
foreach($scales as $scale) {
$line = array();
$line[] = $scale->get_name() .'<div class="scale_options">'.str_replace(",", ", ", $scale->scale).'</div>';
$used = $scale->is_used();
$line[] = $used ? get_string('yes') : get_string('no');
$buttons = "";
$buttons .= grade_button('edit', $courseid, $scale);
if (!$used) {
$buttons .= grade_button('delete', $courseid, $scale);
}
$line[] = $buttons;
$data[] = $line;
}
$table->head = array($strscale, $strused, $stredit);
$table->size = array('70%', '20%', '10%');
$table->align = array('left', 'center', 'center');
$table->attributes['class'] = 'scaletable localscales generaltable';
$table->data = $data;
}
if ($scales = grade_scale::fetch_all_global()) {
$heading = $strstandardscale;
$data = array();
foreach($scales as $scale) {
$line = array();
$line[] = $scale->get_name().'<div class="scale_options">'.str_replace(",", ", ", $scale->scale).'</div>';
$used = $scale->is_used();
$line[] = $used ? get_string('yes') : get_string('no');
$buttons = "";
if (has_capability('moodle/course:managescales', context_system::instance())) {
$buttons .= grade_button('edit', $courseid, $scale);
}
if (!$used and has_capability('moodle/course:managescales', context_system::instance())) {
$buttons .= grade_button('delete', $courseid, $scale);
}
$line[] = $buttons;
$data[] = $line;
}
$table2->head = array($strscale, $strused, $stredit);
$table->attributes['class'] = 'scaletable globalscales generaltable';
$table2->size = array('70%', '20%', '10%');
$table2->align = array('left', 'center', 'center');
$table2->data = $data;
}
$actionbar = new \core_grades\output\scales_action_bar($context);
if ($courseid) {
print_grade_page_head($courseid, 'scale', 'scale', false,
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'));
}
$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();
+146
View File
@@ -0,0 +1,146 @@
<?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/>.
/**
* A form for editing course grade settings
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once($CFG->libdir.'/formslib.php');
/**
* First implementation of the preferences in the form of a moodleform.
* TODO add "reset to site defaults" button
*/
class course_settings_form extends moodleform {
function definition() {
global $USER, $CFG;
$mform =& $this->_form;
$systemcontext = context_system::instance();
$can_view_admin_links = false;
if (has_capability('moodle/grade:manage', $systemcontext)) {
$can_view_admin_links = true;
}
// General settings
$strchangedefaults = get_string('changedefaults', 'grades');
$mform->addElement('header', 'general', get_string('generalsettings', 'grades'));
if ($can_view_admin_links) {
$link = '<a href="' . $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=gradessettings">' . $strchangedefaults . '</a>';
$mform->addElement('static', 'generalsettingslink', null, $link);
}
$options = array(-1 => get_string('default', 'grades'),
GRADE_REPORT_AGGREGATION_POSITION_FIRST => get_string('positionfirst', 'grades'),
GRADE_REPORT_AGGREGATION_POSITION_LAST => get_string('positionlast', 'grades'));
$default_gradedisplaytype = $CFG->grade_aggregationposition;
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[-1] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'aggregationposition', get_string('aggregationposition', 'grades'), $options);
$mform->addHelpButton('aggregationposition', 'aggregationposition', 'grades');
if ($CFG->grade_minmaxtouse == GRADE_MIN_MAX_FROM_GRADE_ITEM) {
$default = get_string('gradeitemminmax', 'grades');
} else if ($CFG->grade_minmaxtouse == GRADE_MIN_MAX_FROM_GRADE_GRADE) {
$default = get_string('gradegrademinmax', 'grades');
} else {
throw new coding_exception('Invalid $CFG->grade_minmaxtouse value.');
}
$options = array(
-1 => get_string('defaultprev', 'grades', $default),
GRADE_MIN_MAX_FROM_GRADE_ITEM => get_string('gradeitemminmax', 'grades'),
GRADE_MIN_MAX_FROM_GRADE_GRADE => get_string('gradegrademinmax', 'grades')
);
$mform->addElement('select', 'minmaxtouse', get_string('minmaxtouse', 'grades'), $options);
$mform->addHelpButton('minmaxtouse', 'minmaxtouse', 'grades');
// Grade item settings
$mform->addElement('header', 'grade_item_settings', get_string('gradeitemsettings', 'grades'));
$mform->setExpanded('grade_item_settings');
if ($can_view_admin_links) {
$link = '<a href="' . $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=gradeitemsettings">' . $strchangedefaults . '</a>';
$mform->addElement('static', 'gradeitemsettingslink', null, $link);
}
$options = array(-1 => get_string('default', 'grades'),
GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'));
$default_gradedisplaytype = $CFG->grade_displaytype;
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[-1] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'displaytype', get_string('gradedisplaytype', 'grades'), $options);
$mform->addHelpButton('displaytype', 'gradedisplaytype', 'grades');
$mform->setDefault('displaytype', -1);
$options = array(-1=> get_string('defaultprev', 'grades', $CFG->grade_decimalpoints), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'decimalpoints', get_string('decimalpoints', 'grades'), $options);
$mform->addHelpButton('decimalpoints', 'decimalpoints', 'grades');
// add setting options for plugins
$types = array('report', 'export', 'import');
foreach($types as $type) {
foreach (core_component::get_plugin_list('grade'.$type) as $plugin => $plugindir) {
// Include all the settings commands for this plugin if there are any
if (file_exists($plugindir.'/lib.php')) {
require_once($plugindir.'/lib.php');
$functionname = 'grade_'.$type.'_'.$plugin.'_settings_definition';
if (function_exists($functionname)) {
$mform->addElement('header', 'grade_'.$type.$plugin, get_string('pluginname', 'grade'.$type.'_'.$plugin, NULL));
$mform->setExpanded('grade_'.$type.$plugin);
if ($can_view_admin_links) {
$link = '<a href="' . $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=gradereport' . $plugin . '">' . $strchangedefaults . '</a>';
$mform->addElement('static', 'gradeitemsettingslink', null, $link);
}
$functionname($mform);
}
}
}
}
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$this->add_action_buttons(false);
}
}
+90
View File
@@ -0,0 +1,90 @@
<?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/>.
/**
* A page for editing course grade settings
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/gradelib.php';
require_once 'form.php';
$courseid = optional_param('id', SITEID, PARAM_INT);
$PAGE->set_url('/grade/edit/settings/index.php', array('id'=>$courseid));
$PAGE->set_pagelayout('admin');
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'settings', 'courseid'=>$courseid));
$strgrades = get_string('grades');
$pagename = get_string('coursesettings', 'grades');
$mform = new course_settings_form();
$settings = grade_get_settings($course->id);
$mform->set_data($settings);
if ($data = $mform->get_data()) {
$data = (array)$data;
$general = array('displaytype', 'decimalpoints', 'aggregationposition', 'minmaxtouse');
foreach ($data as $key=>$value) {
if (!in_array($key, $general) and strpos($key, 'report_') !== 0
and strpos($key, 'import_') !== 0
and strpos($key, 'export_') !== 0) {
continue;
}
if ($value == -1) {
$value = null;
}
grade_set_setting($course->id, $key, $value);
$previousvalue = isset($settings->{$key}) ? $settings->{$key} : null;
if ($key == 'minmaxtouse' && $previousvalue != $value) {
// The min max has changed, we need to regrade the grades.
grade_force_full_regrading($courseid);
}
}
}
print_grade_page_head($courseid, 'settings', 'coursesettings');
// The settings could have been changed due to a notice shown in print_grade_page_head, we need to refresh them.
$settings = grade_get_settings($course->id);
$mform->set_data($settings);
echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal centerpara');
echo get_string('coursesettingsexplanation', 'grades');
echo $OUTPUT->box_end();
$mform->display();
echo $OUTPUT->footer();
+146
View File
@@ -0,0 +1,146 @@
<?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/>.
/**
* Performs actions on grade items and categories like hiding and locking
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
$courseid = required_param('id', PARAM_INT);
$action = required_param('action', PARAM_ALPHA);
$eid = required_param('eid', PARAM_ALPHANUM);
$PAGE->set_url('/grade/edit/tree/action.php', array('id'=>$courseid, 'action'=>$action, 'eid'=>$eid));
/// Make sure they can even access this course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/edit/tree/index.php?id='.$course->id);
// get the grading tree object
$gtree = new grade_tree($courseid, false, false);
// what are we working with?
if (!$element = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object = $element['object'];
$type = $element['type'];
switch ($action) {
case 'hide':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
throw new \moodle_exception('nopermissiontohide', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
if (!$object->can_control_visibility()) {
throw new \moodle_exception('componentcontrolsvisibility', 'grades', $returnurl);
}
$object->set_hidden(1, true);
}
break;
case 'show':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
throw new \moodle_exception('nopermissiontoshow', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
if (!$object->can_control_visibility()) {
throw new \moodle_exception('componentcontrolsvisibility', 'grades', $returnurl);
}
$object->set_hidden(0, true);
}
break;
case 'lock':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context)) {
throw new \moodle_exception('nopermissiontolock', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
$object->set_locked(1, false, true);
}
break;
case 'unlock':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context)) {
throw new \moodle_exception('nopermissiontounlock', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
$object->set_locked(0, false, true);
}
break;
case 'resetweights':
if ($eid && confirm_sesskey()) {
// This is specific to category items with natural weight as an aggregation method, and can
// only be done by someone who can manage the grades.
if ($type != 'category' || $object->aggregation != GRADE_AGGREGATE_SUM ||
!has_capability('moodle/grade:manage', $context)) {
throw new \moodle_exception('nopermissiontoresetweights', 'grades', $returnurl);
}
// Remove the weightoverride flag from the children.
$children = $object->get_children();
foreach ($children as $item) {
if ($item['type'] == 'category') {
$gradeitem = $item['object']->load_grade_item();
} else {
$gradeitem = $item['object'];
}
if ($gradeitem->weightoverride == false) {
continue;
}
$gradeitem->weightoverride = false;
$gradeitem->update();
}
// Force regrading.
$object->force_regrading();
}
}
redirect($returnurl);
//redirect($returnurl, 'debug delay', 5);
+220
View File
@@ -0,0 +1,220 @@
<?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/>.
/**
* Edit a calculated grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/mathslib.php';
require_once 'calculation_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = required_param('id', PARAM_INT);
$section = optional_param('section', 'calculation', PARAM_ALPHA);
$idnumbers = optional_param_array('idnumbers', null, PARAM_RAW);
$url = new moodle_url('/grade/edit/tree/calculation.php', array('id'=>$id, 'courseid'=>$courseid));
if ($section !== 'calculation') {
$url->param('section', $section);
}
$PAGE->set_url($url);
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$course->id)));
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report/index.php?id='.$course->id);
if (!$grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
throw new \moodle_exception('invaliditemid');
}
// activity items and items without grade can not have calculation
if ($grade_item->is_external_item() or ($grade_item->gradetype != GRADE_TYPE_VALUE and $grade_item->gradetype != GRADE_TYPE_SCALE)) {
redirect($returnurl, get_string('errornocalculationallowed', 'grades'));
}
$mform = new edit_calculation_form(null, array('gpr'=>$gpr, 'itemid' => $grade_item->id));
if ($mform->is_cancelled()) {
redirect($returnurl);
}
$calculation = calc_formula::localize($grade_item->calculation);
$calculation = grade_item::denormalize_formula($calculation, $grade_item->courseid);
$mform->set_data(array('courseid'=>$grade_item->courseid, 'calculation'=>$calculation, 'id'=>$grade_item->id, 'itemname'=>$grade_item->itemname));
$errors = array();
if ($data = $mform->get_data()) {
$calculation = calc_formula::unlocalize($data->calculation);
$grade_item->set_calculation($calculation);
redirect($returnurl);
} elseif (!empty($section) AND $section='idnumbers' AND !empty($idnumbers)) { // Handle idnumbers separately (non-mform)
//first validate and store the new idnumbers
foreach ($idnumbers as $giid => $value) {
if ($gi = grade_item::fetch(array('id' => $giid))) {
if ($gi->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($gi->itemmodule, $gi->iteminstance, $gi->courseid);
} else {
$cm = null;
}
if (!grade_verify_idnumber($value, $COURSE->id, $gi, $cm)) {
$errors[$giid] = get_string('idnumbertaken');
continue;
}
if (empty($gi->idnumber) and !$gi->add_idnumber($idnumbers[$gi->id])) {
$errors[$giid] = get_string('error');
continue;
}
} else {
$errors[$giid] = 'Could not fetch the grade_item with id=' . $giid;
}
}
}
$gtree = new grade_tree($course->id, false, false);
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$strcalculationedit = get_string('editcalculation', 'grades');
$PAGE->navbar->add($strcalculationedit);
print_grade_page_head($courseid, 'settings', null, $strcalculationedit, false, false, false);
$mform->display();
// Now show the gradetree with the idnumbers add/edit form
echo '
<form class="mform" id="mform2" method="post" action="' . $CFG->wwwroot . '/grade/edit/tree/calculation.php?courseid='.$courseid.'&amp;id='.$id.'">
<div style="display: none;">
<input type="hidden" value="'.$id.'" name="id"/>
<input type="hidden" value="'.$courseid.'" name="courseid"/>
<input type="hidden" value="'.$gpr->type.'" name="gpr_type"/>
<input type="hidden" value="'.$gpr->plugin.'" name="gpr_plugin"/>
<input type="hidden" value="'.$gpr->courseid.'" name="gpr_courseid"/>
<input type="hidden" value="'.sesskey().'" name="sesskey"/>
<input type="hidden" value="idnumbers" name="section"/>
</div>
<fieldset id="idnumbers" class="clearfix">
<legend class="ftoggler">'.get_string('idnumbers', 'grades').'</legend>
<div class="fcontainer clearfix">
<ul>
' . get_grade_tree($gtree, $gtree->top_element, $id, $errors) . '
</ul>
</div>
</fieldset>
<div class="fitem" style="text-align: center;">
<input id="id_addidnumbers" type="submit" class="btn btn-secondary" value="' . get_string('addidnumbers', 'grades') . '" name="addidnumbers" />
</div>
</form>';
echo $OUTPUT->footer();
die();
/**
* Simplified version of the print_grade_tree() recursive function found in grade/edit/tree/index.php
* Only prints a tree with a basic icon for each element, and an edit field for
* items without an idnumber.
* @param object $gtree
* @param object $element
* @param int $current_itemid The itemid of this page: should be excluded from the tree
* @param array $errors An array of idnumbers => error
* @return string
*/
function get_grade_tree(&$gtree, $element, $current_itemid=null, $errors=null) {
global $CFG;
$object = $element['object'];
$eid = $element['eid'];
$type = $element['type'];
$grade_item = $object->get_grade_item();
$name = $object->get_name();
$return_string = '';
//TODO: improve outcome visualisation
if ($type == 'item' and !empty($object->outcomeid)) {
$name = $name.' ('.get_string('outcome', 'grades').')';
}
$idnumber = $object->get_idnumber();
// Don't show idnumber or input field for current item if given to function. Highlight the item instead.
if ($type != 'category') {
if (is_null($current_itemid) OR $grade_item->id != $current_itemid) {
if ($idnumber) {
$name .= ": [[$idnumber]]";
} else {
$closingdiv = '';
if (!empty($errors[$grade_item->id])) {
$name .= '<div class="error"><span class="error">' . $errors[$grade_item->id].'</span><br />'."\n";
$closingdiv = "</div>\n";
}
$name .= '<label class="accesshide" for="id_idnumber_' . $grade_item->id . '">' . get_string('gradeitems', 'grades') .'</label>';
$name .= '<input class="idnumber" id="id_idnumber_'.$grade_item->id.'" type="text" name="idnumbers['.$grade_item->id.']" />' . "\n";
$name .= $closingdiv;
}
} else {
$name = "<strong>$name</strong>";
}
}
$icon = grade_helper::get_element_icon($element, true);
$last = '';
$catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
if ($type != 'category') {
$return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n";
} else {
$return_string .= '<li class="'.$type.'">'.$icon.$name . "\n";
$return_string .= '<ul class="catlevel'.$element['depth'].'">'."\n";
$last = null;
foreach($element['children'] as $child_el) {
$return_string .= get_grade_tree($gtree, $child_el, $current_itemid, $errors);
}
if ($last) {
$return_string .= get_grade_tree($gtree, $last, $current_itemid, $errors);
}
$return_string .= '</ul></li>'."\n";
}
return $return_string;
}
+108
View File
@@ -0,0 +1,108 @@
<?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/>.
/**
* A moodleform to allow the editing of a calculated grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_calculation_form extends moodleform {
public $available;
public $noidnumbers;
function definition() {
global $COURSE;
$mform =& $this->_form;
$itemid = $this->_customdata['itemid'];
$this->available = grade_item::fetch_all(array('courseid'=>$COURSE->id));
$this->noidnumbers = array();
// All items that have no idnumbers are added to a separate section of the form (hidden by default),
// enabling the user to assign idnumbers to these grade_items.
foreach ($this->available as $item) {
if (empty($item->idnumber)) {
$this->noidnumbers[$item->id] = $item;
unset($this->available[$item->id]);
}
if ($item->id == $itemid) { // Do not include the current grade_item in the available section
unset($this->available[$item->id]);
}
}
/// visible elements
$mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
$mform->addElement('static', 'itemname', get_string('itemname', 'grades'));
$mform->addElement('textarea', 'calculation', get_string('calculation', 'grades'), 'cols="60" rows="5"');
$mform->addHelpButton('calculation', 'calculation', 'grades');
$mform->setForceLtr('calculation');
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
$mform->addElement('hidden', 'section', 0);
$mform->setType('section', PARAM_ALPHA);
$mform->setDefault('section', 'calculation');
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
$this->add_action_buttons();
}
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
}
/// perform extra validation before submission
function validation($data, $files) {
$errors = parent::validation($data, $files);
$mform =& $this->_form;
// check the calculation formula
if ($data['calculation'] != '') {
$grade_item = grade_item::fetch(array('id'=>$data['id'], 'courseid'=>$data['courseid']));
$calculation = calc_formula::unlocalize(stripslashes($data['calculation']));
$result = $grade_item->validate_formula($calculation);
if ($result !== true) {
$errors['calculation'] = $result;
}
}
return $errors;
}
}
+155
View File
@@ -0,0 +1,155 @@
<?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/>.
/**
* Edit the grade options for an individual grade category
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_category;
require_once('../../../config.php');
require_once($CFG->dirroot.'/grade/lib.php');
require_once($CFG->dirroot.'/grade/edit/tree/lib.php');
require_once($CFG->dirroot.'/grade/report/lib.php');
require_once('category_form.php');
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT); // grade_category->id
$url = new moodle_url('/grade/edit/tree/category.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$heading = get_string('categoryedit', 'grades');
if ($id) {
if (!$grade_category = grade_category::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
throw new \moodle_exception('invalidcategory');
}
$grade_category->apply_forced_settings();
$category = $grade_category->get_record_data();
// set parent
$category->parentcategory = $grade_category->parent;
$grade_item = $grade_category->load_grade_item();
// nomalize coef values if needed
$parent_category = $grade_category->get_parent_category();
foreach ($grade_item->get_record_data() as $key => $value) {
$category->{"grade_item_$key"} = $value;
}
$decimalpoints = $grade_item->get_decimals();
$category->grade_item_grademax = format_float($category->grade_item_grademax, $decimalpoints);
$category->grade_item_grademin = format_float($category->grade_item_grademin, $decimalpoints);
$category->grade_item_gradepass = format_float($category->grade_item_gradepass, $decimalpoints);
$category->grade_item_multfactor = format_float($category->grade_item_multfactor, 4);
$category->grade_item_plusfactor = format_float($category->grade_item_plusfactor, 4);
$category->grade_item_aggregationcoef2 = format_float($category->grade_item_aggregationcoef2 * 100.0, 4);
if (!$parent_category) {
// keep as is
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM or $parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$category->grade_item_aggregationcoef = $category->grade_item_aggregationcoef == 0 ? 0 : 1;
} else {
$category->grade_item_aggregationcoef = format_float($category->grade_item_aggregationcoef, 4);
}
// Check to see if the gradebook is frozen. This allows grades to not be altered at all until a user verifies that they
// wish to update the grades.
$gradebookcalculationsfreeze = get_config('core', 'gradebook_calculations_freeze_' . $courseid);
// Stick with the original code if the grade book is frozen.
if ($gradebookcalculationsfreeze && (int)$gradebookcalculationsfreeze <= 20150627) {
if ($category->aggregation == GRADE_AGGREGATE_SUM) {
// Input fields for grademin and grademax are disabled for the "Natural" category,
// this means they will be ignored if user does not change aggregation method.
// But if user does change aggregation method the default values should be used.
$category->grademax = 100;
$category->grade_item_grademax = 100;
$category->grademin = 0;
$category->grade_item_grademin = 0;
}
} else {
if ($category->aggregation == GRADE_AGGREGATE_SUM && !$grade_item->is_calculated()) {
// Input fields for grademin and grademax are disabled for the "Natural" category,
// this means they will be ignored if user does not change aggregation method.
// But if user does change aggregation method the default values should be used.
// This does not apply to calculated category totals.
$category->grademax = 100;
$category->grade_item_grademax = 100;
$category->grademin = 0;
$category->grade_item_grademin = 0;
}
}
} else {
$heading = get_string('newcategory', 'grades');
$grade_category = new grade_category(array('courseid'=>$courseid), false);
$grade_category->apply_default_settings();
$grade_category->apply_forced_settings();
$category = $grade_category->get_record_data();
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
foreach ($grade_item->get_record_data() as $key => $value) {
$category->{"grade_item_$key"} = $value;
}
}
$mform = new edit_category_form(null, array('current'=>$category, 'gpr'=>$gpr));
$simpleform = new add_category(null, ['category' => $grade_category->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
grade_edit_tree::update_gradecategory($grade_category, $data);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
$mform->display();
echo $OUTPUT->footer();
die;
+554
View File
@@ -0,0 +1,554 @@
<?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/>.
/**
* A moodleform to edit the grade options for an individual grade category
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_category_form extends moodleform {
private $aggregation_options = array();
function definition() {
global $CFG, $COURSE, $DB, $OUTPUT;
$mform =& $this->_form;
$category = $this->_customdata['current'];
$this->aggregation_options = grade_helper::get_aggregation_strings();
// visible elements
$mform->addElement('header', 'headercategory', get_string('gradecategory', 'grades'));
$mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
$mform->setType('fullname', PARAM_TEXT);
$mform->addRule('fullname', null, 'required', null, 'client');
$mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $this->aggregation_options);
$mform->addHelpButton('aggregation', 'aggregation', 'grades');
$mform->addElement('checkbox', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades'));
$mform->addHelpButton('aggregateonlygraded', 'aggregateonlygraded', 'grades');
if (empty($CFG->enableoutcomes)) {
$mform->addElement('hidden', 'aggregateoutcomes');
$mform->setType('aggregateoutcomes', PARAM_INT);
} else {
$mform->addElement('checkbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
$mform->addHelpButton('aggregateoutcomes', 'aggregateoutcomes', 'grades');
}
$mform->addElement('text', 'keephigh', get_string('keephigh', 'grades'), 'size="3"');
$mform->setType('keephigh', PARAM_INT);
$mform->addHelpButton('keephigh', 'keephigh', 'grades');
$mform->addElement('text', 'droplow', get_string('droplow', 'grades'), 'size="3"');
$mform->setType('droplow', PARAM_INT);
$mform->addHelpButton('droplow', 'droplow', 'grades');
$mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
$mform->disabledIf('keephigh', 'droplow', 'noteq', 0);
$mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
// Grade item settings
// Displayed as Category total to avoid confusion between grade items requiring marking and category totals
$mform->addElement('header', 'general', get_string('categorytotal', 'grades'));
$mform->setExpanded('general');
$mform->addElement('text', 'grade_item_itemname', get_string('categorytotalname', 'grades'));
$mform->setType('grade_item_itemname', PARAM_TEXT);
$mform->addElement('text', 'grade_item_iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('grade_item_iteminfo', 'iteminfo', 'grades');
$mform->setType('grade_item_iteminfo', PARAM_TEXT);
$mform->addElement('text', 'grade_item_idnumber', get_string('idnumbermod'));
$mform->addHelpButton('grade_item_idnumber', 'idnumbermod');
$mform->setType('grade_item_idnumber', PARAM_RAW);
if (!empty($category->id)) {
$gradecategory = grade_category::fetch(array('id' => $category->id));
$gradeitem = $gradecategory->load_grade_item();
// If grades exist set a message so the user knows why they can not alter the grade type or scale.
// We could never change the grade type for external items, so only need to show this for manual grade items.
if ($gradeitem->has_overridden_grades()) {
// Set a message so the user knows why the can not alter the grade type or scale.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$gradesexistmsg = get_string('modgradecategorycantchangegradetyporscalemsg', 'grades');
} else {
$gradesexistmsg = get_string('modgradecategorycantchangegradetypemsg', 'grades');
}
$notification = new \core\output\notification($gradesexistmsg, \core\output\notification::NOTIFY_INFO);
$notification->set_show_closebutton(false);
$mform->addElement('static', 'gradesexistmsg', '', $OUTPUT->render($notification));
}
}
$options = array(GRADE_TYPE_NONE=>get_string('typenone', 'grades'),
GRADE_TYPE_VALUE=>get_string('typevalue', 'grades'),
GRADE_TYPE_SCALE=>get_string('typescale', 'grades'),
GRADE_TYPE_TEXT=>get_string('typetext', 'grades'));
$mform->addElement('select', 'grade_item_gradetype', get_string('gradetype', 'grades'), $options);
$mform->addHelpButton('grade_item_gradetype', 'gradetype', 'grades');
$mform->setDefault('grade_item_gradetype', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_gradetype', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
//$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
$options = array(0=>get_string('usenoscale', 'grades'));
if ($scales = grade_scale::fetch_all_local($COURSE->id)) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
if ($scales = grade_scale::fetch_all_global()) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
// ugly BC hack - it was possible to use custom scale from other courses :-(
if (!empty($category->grade_item_scaleid) and !isset($options[$category->grade_item_scaleid])) {
if ($scale = grade_scale::fetch(array('id'=>$category->grade_item_scaleid))) {
$options[$scale->id] = $scale->get_name().' '.get_string('incorrectcustomscale', 'grades');
}
}
$mform->addElement('select', 'grade_item_scaleid', get_string('scale'), $options);
$mform->addHelpButton('grade_item_scaleid', 'typescale', 'grades');
$mform->disabledIf('grade_item_scaleid', 'grade_item_gradetype', 'noteq', GRADE_TYPE_SCALE);
$mform->disabledIf('grade_item_scaleid', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
$choices = array();
$choices[''] = get_string('choose');
$choices['no'] = get_string('no');
$choices['yes'] = get_string('yes');
$mform->addElement('select', 'grade_item_rescalegrades', get_string('modgradecategoryrescalegrades', 'grades'), $choices);
$mform->addHelpButton('grade_item_rescalegrades', 'modgradecategoryrescalegrades', 'grades');
$mform->disabledIf('grade_item_rescalegrades', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->addElement('float', 'grade_item_grademax', get_string('grademax', 'grades'));
$mform->addHelpButton('grade_item_grademax', 'grademax', 'grades');
$mform->disabledIf('grade_item_grademax', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_grademax', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
if ((bool) get_config('moodle', 'grade_report_showmin')) {
$mform->addElement('float', 'grade_item_grademin', get_string('grademin', 'grades'));
$mform->addHelpButton('grade_item_grademin', 'grademin', 'grades');
$mform->disabledIf('grade_item_grademin', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_grademin', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
}
$mform->addElement('float', 'grade_item_gradepass', get_string('gradepass', 'grades'));
$mform->addHelpButton('grade_item_gradepass', 'gradepass', 'grades');
$mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
/// grade display prefs
$default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
$options = array(GRADE_DISPLAY_TYPE_DEFAULT => get_string('default', 'grades'),
GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades')
);
asort($options);
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'grade_item_display', get_string('gradedisplaytype', 'grades'), $options);
$mform->addHelpButton('grade_item_display', 'gradedisplaytype', 'grades');
$mform->disabledIf('grade_item_display', 'grade_item_gradetype', 'in',
array(GRADE_TYPE_TEXT, GRADE_TYPE_NONE));
$default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
$options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'grade_item_decimals', get_string('decimalpoints', 'grades'), $options);
$mform->addHelpButton('grade_item_decimals', 'decimalpoints', 'grades');
$mform->setDefault('grade_item_decimals', -1);
$mform->disabledIf('grade_item_decimals', 'grade_item_display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
$mform->disabledIf('grade_item_decimals', 'grade_item_gradetype', 'in',
array(GRADE_TYPE_TEXT, GRADE_TYPE_NONE));
if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
$mform->disabledIf('grade_item_decimals', 'grade_item_display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
}
/// hiding
// advcheckbox is not compatible with disabledIf!
$mform->addElement('checkbox', 'grade_item_hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('grade_item_hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'grade_item_hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('grade_item_hidden', 'grade_item_hiddenuntil[enabled]', 'checked');
/// locking
$mform->addElement('checkbox', 'grade_item_locked', get_string('locked', 'grades'));
$mform->addHelpButton('grade_item_locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'grade_item_locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('grade_item_locktime', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->setExpanded('headerparent');
$mform->addElement('advcheckbox', 'grade_item_weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('grade_item_weightoverride', 'weightoverride', 'grades');
$mform->addElement('float', 'grade_item_aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('grade_item_aggregationcoef2', 'weight', 'grades');
$mform->disabledIf('grade_item_aggregationcoef2', 'grade_item_weightoverride');
$options = array();
$default = -1;
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
if ($cat->is_course_category()) {
$default = $cat->id;
}
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('parentcategory', 'grades'), $options);
$mform->setDefault('parentcategory', $default);
$mform->addElement('static', 'currentparentaggregation', get_string('currentparentaggregation', 'grades'));
}
// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
//-------------------------------------------------------------------------------
$this->set_data($category);
}
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
$somecat = new grade_category();
foreach ($somecat->forceable as $property) {
if ((int)$CFG->{"grade_{$property}_flag"} & 1) {
if ($mform->elementExists($property)) {
if (empty($CFG->grade_hideforcedsettings)) {
$mform->hardFreeze($property);
} else {
if ($mform->elementExists($property)) {
$mform->removeElement($property);
}
}
}
}
}
if ($CFG->grade_droplow > 0) {
if ($mform->elementExists('keephigh')) {
$mform->removeElement('keephigh');
}
} else if ($CFG->grade_keephigh > 0) {
if ($mform->elementExists('droplow')) {
$mform->removeElement('droplow');
}
}
if ($id = $mform->getElementValue('id')) {
$grade_category = grade_category::fetch(array('id'=>$id));
$grade_item = $grade_category->load_grade_item();
// remove agg coef if not used
if ($grade_category->is_course_category()) {
if ($mform->elementExists('parentcategory')) {
$mform->removeElement('parentcategory');
}
if ($mform->elementExists('currentparentaggregation')) {
$mform->removeElement('currentparentaggregation');
}
} else {
// if we wanted to change parent of existing category - we would have to verify there are no circular references in parents!!!
if ($mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
$parent_cat = $grade_category->get_parent_category();
$mform->setDefault('currentparentaggregation', $this->aggregation_options[$parent_cat->aggregation]);
}
// Prevent the user from using drop lowest/keep highest when the aggregation method cannot handle it.
if (!$grade_category->can_apply_limit_rules()) {
if ($mform->elementExists('keephigh')) {
$mform->setConstant('keephigh', 0);
$mform->hardFreeze('keephigh');
}
if ($mform->elementExists('droplow')) {
$mform->setConstant('droplow', 0);
$mform->hardFreeze('droplow');
}
}
if ($grade_item->is_calculated()) {
// following elements are ignored when calculation formula used
if ($mform->elementExists('aggregation')) {
$mform->removeElement('aggregation');
}
if ($mform->elementExists('keephigh')) {
$mform->removeElement('keephigh');
}
if ($mform->elementExists('droplow')) {
$mform->removeElement('droplow');
}
if ($mform->elementExists('aggregateonlygraded')) {
$mform->removeElement('aggregateonlygraded');
}
if ($mform->elementExists('aggregateoutcomes')) {
$mform->removeElement('aggregateoutcomes');
}
}
// If it is a course category, remove the "required" rule from the "fullname" element
if ($grade_category->is_course_category()) {
unset($mform->_rules['fullname']);
$key = array_search('fullname', $mform->_required);
unset($mform->_required[$key]);
}
// If it is a course category and its fullname is ?, show an empty field
if ($grade_category->is_course_category() && $mform->getElementValue('fullname') == '?') {
$mform->setDefault('fullname', '');
}
// remove unwanted aggregation options
if ($mform->elementExists('aggregation')) {
$allaggoptions = array_keys($this->aggregation_options);
$agg_el =& $mform->getElement('aggregation');
$visible = explode(',', $CFG->grade_aggregations_visible);
if (!is_null($grade_category->aggregation)) {
// current type is always visible
$visible[] = $grade_category->aggregation;
}
foreach ($allaggoptions as $type) {
if (!in_array($type, $visible)) {
$agg_el->removeOption($type);
}
}
}
} else {
// adding new category
if ($mform->elementExists('currentparentaggregation')) {
$mform->removeElement('currentparentaggregation');
}
// remove unwanted aggregation options
if ($mform->elementExists('aggregation')) {
$allaggoptions = array_keys($this->aggregation_options);
$agg_el =& $mform->getElement('aggregation');
$visible = explode(',', $CFG->grade_aggregations_visible);
foreach ($allaggoptions as $type) {
if (!in_array($type, $visible)) {
$agg_el->removeOption($type);
}
}
}
$mform->removeElement('grade_item_rescalegrades');
}
// no parent header for course category
if (!$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
/// GRADE ITEM
if ($id = $mform->getElementValue('id')) {
$grade_category = grade_category::fetch(array('id'=>$id));
$grade_item = $grade_category->load_grade_item();
// Load appropriate "hidden"/"hidden until" defaults.
if ($grade_item->is_hiddenuntil()) {
$mform->setDefault('grade_item_hiddenuntil', $grade_item->get_hidden());
} else {
$mform->setDefault('grade_item_hidden', $grade_item->get_hidden());
}
if ($grade_item->is_outcome_item()) {
// we have to prevent incompatible modifications of outcomes if outcomes disabled
$mform->removeElement('grade_item_grademax');
if ($mform->elementExists('grade_item_grademin')) {
$mform->removeElement('grade_item_grademin');
}
$mform->removeElement('grade_item_gradetype');
$mform->removeElement('grade_item_display');
$mform->removeElement('grade_item_decimals');
$mform->hardFreeze('grade_item_scaleid');
// Only show the option to rescale grades on a category if its corresponding grade_item has overridden grade_grades.
} else if ($grade_item->has_overridden_grades()) {
// Can't change the grade type or the scale if there are grades.
$mform->hardFreeze('grade_item_gradetype, grade_item_scaleid');
// If we are using scles then remove the unnecessary rescale and grade fields.
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('grade_item_rescalegrades');
$mform->removeElement('grade_item_grademax');
if ($mform->elementExists('grade_item_grademin')) {
$mform->removeElement('grade_item_grademin');
}
} else { // Not using scale, so remove it.
$mform->removeElement('grade_item_scaleid');
$mform->disabledIf('grade_item_grademax', 'grade_item_rescalegrades', 'eq', '');
$mform->disabledIf('grade_item_grademin', 'grade_item_rescalegrades', 'eq', '');
}
} else { // Remove the rescale element if there are no grades.
$mform->removeElement('grade_item_rescalegrades');
}
//remove the aggregation coef element if not needed
if ($grade_item->is_course_item()) {
if ($mform->elementExists('grade_item_aggregationcoef')) {
$mform->removeElement('grade_item_aggregationcoef');
}
if ($mform->elementExists('grade_item_weightoverride')) {
$mform->removeElement('grade_item_weightoverride');
}
if ($mform->elementExists('grade_item_aggregationcoef2')) {
$mform->removeElement('grade_item_aggregationcoef2');
}
} else {
if ($grade_item->is_category_item()) {
$category = $grade_item->get_item_category();
$parent_category = $category->get_parent_category();
} else {
$parent_category = $grade_item->get_parent_category();
}
$parent_category->apply_forced_settings();
if (!$parent_category->is_aggregationcoef_used()) {
if ($mform->elementExists('grade_item_aggregationcoef')) {
$mform->removeElement('grade_item_aggregationcoef');
}
} else {
$coefstring = $grade_item->get_coefstring();
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$element =& $mform->createElement('checkbox', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
} else {
$element =& $mform->createElement('text', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
}
$mform->insertElementBefore($element, 'parentcategory');
$mform->addHelpButton('grade_item_aggregationcoef', $coefstring, 'grades');
}
// Remove fields used by natural weighting if the parent category is not using natural weighting.
// Or if the item is a scale and scales are not used in aggregation.
if ($parent_category->aggregation != GRADE_AGGREGATE_SUM
|| (empty($CFG->grade_includescalesinaggregation) && $grade_item->gradetype == GRADE_TYPE_SCALE)) {
if ($mform->elementExists('grade_item_weightoverride')) {
$mform->removeElement('grade_item_weightoverride');
}
if ($mform->elementExists('grade_item_aggregationcoef2')) {
$mform->removeElement('grade_item_aggregationcoef2');
}
}
}
}
}
function validation($data, $files) {
global $COURSE;
$gradeitem = false;
if ($data['id']) {
$gradecategory = grade_category::fetch(array('id' => $data['id']));
$gradeitem = $gradecategory->load_grade_item();
}
$errors = parent::validation($data, $files);
if (array_key_exists('grade_item_gradetype', $data) and $data['grade_item_gradetype'] == GRADE_TYPE_SCALE) {
if (empty($data['grade_item_scaleid'])) {
$errors['grade_item_scaleid'] = get_string('missingscale', 'grades');
}
}
// We need to make all the validations related with grademax and grademin
// with them being correct floats, keeping the originals unmodified for
// later validations / showing the form back...
// TODO: Note that once MDL-73994 is fixed we'll have to re-visit this and
// adapt the code below to the new values arriving here, without forgetting
// the special case of empties and nulls.
$grademax = isset($data['grade_item_grademax']) ? unformat_float($data['grade_item_grademax']) : null;
$grademin = isset($data['grade_item_grademin']) ? unformat_float($data['grade_item_grademin']) : null;
if (!is_null($grademin) and !is_null($grademax)) {
if (($grademax != 0 OR $grademin != 0) AND
($grademax == $grademin OR $grademax < $grademin)) {
$errors['grade_item_grademin'] = get_string('incorrectminmax', 'grades');
$errors['grade_item_grademax'] = get_string('incorrectminmax', 'grades');
}
}
if ($data['id'] && $gradeitem->has_overridden_grades()) {
if ($gradeitem->gradetype == GRADE_TYPE_VALUE) {
if (grade_floats_different($grademin, $gradeitem->grademin) ||
grade_floats_different($grademax, $gradeitem->grademax)) {
if (empty($data['grade_item_rescalegrades'])) {
$errors['grade_item_rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
}
}
}
}
return $errors;
}
}
+292
View File
@@ -0,0 +1,292 @@
<?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/>.
/**
* Edit a user's grade for a particular activity
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'grade_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$itemid = optional_param('itemid', 0, PARAM_INT);
$userid = optional_param('userid', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/grade.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
if ($itemid !== 0) {
$url->param('itemid', $itemid);
}
if ($userid !== 0) {
$url->param('userid', $userid);
}
$PAGE->set_url($url);
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
$PAGE->set_pagelayout('incourse');
require_login($course);
$context = context_course::instance($course->id);
if (!has_capability('moodle/grade:manage', $context)) {
require_capability('moodle/grade:edit', $context);
}
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report/index.php?id='.$course->id);
// security checks!
if (!empty($id)) {
if (!$grade = $DB->get_record('grade_grades', array('id' => $id))) {
throw new \moodle_exception('invalidgroupid');
}
if (!empty($itemid) and $itemid != $grade->itemid) {
throw new \moodle_exception('invaliditemid');
}
$itemid = $grade->itemid;
if (!empty($userid) and $userid != $grade->userid) {
throw new \moodle_exception('invaliduser');
}
$userid = $grade->userid;
unset($grade);
} else if (empty($userid) or empty($itemid)) {
throw new \moodle_exception('missinguseranditemid');
}
if (!$grade_item = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$courseid))) {
throw new \moodle_exception('cannotfindgradeitem');
}
// now verify grading user has access to all groups or is member of the same group when separate groups used in course
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if ($groups = groups_get_all_groups($COURSE->id, $userid)) {
$ok = false;
foreach ($groups as $group) {
if (groups_is_member($group->id, $USER->id)) {
$ok = true;
}
}
if (!$ok) {
throw new \moodle_exception('cannotgradeuser');
}
} else {
throw new \moodle_exception('cannotgradeuser');
}
}
$mform = new edit_grade_form(null, array('grade_item'=>$grade_item, 'gpr'=>$gpr));
if ($grade = $DB->get_record('grade_grades', array('itemid' => $grade_item->id, 'userid' => $userid))) {
// always clean existing feedback - grading should not have XSS risk
if (empty($grade->feedback)) {
$grade->feedback = '';
} else {
$options = new stdClass();
$options->filter = false;
$options->noclean = false;
$options->para = false;
$grade->feedback = format_text($grade->feedback, $grade->feedbackformat, $options);
}
$grade->feedbackformat = FORMAT_HTML;
$grade->locked = $grade->locked > 0 ? 1:0;
$grade->overridden = $grade->overridden > 0 ? 1:0;
$grade->excluded = $grade->excluded > 0 ? 1:0;
if ($grade->hidden > 1) {
$grade->hiddenuntil = $grade->hidden;
$grade->hidden = 1;
} else {
$grade->hiddenuntil = 0;
}
if ($grade_item->is_hidden()) {
$grade->hidden = 1;
}
if ($grade_item->is_locked()) {
$grade->locked = 1;
}
// normalize the final grade value
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if (empty($grade->finalgrade)) {
$grade->finalgrade = -1;
} else {
$grade->finalgrade = (int)$grade->finalgrade;
}
} else if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
$grade->finalgrade = format_float($grade->finalgrade, $grade_item->get_decimals());
}
$grade->oldgrade = $grade->finalgrade;
$grade->oldfeedback = $grade->feedback;
$grade->feedback = array('text'=>$grade->feedback, 'format'=>$grade->feedbackformat);
$mform->set_data($grade);
} else {
$grade = new stdClass();
$grade->feedback = array('text'=>'', 'format'=>FORMAT_HTML);
$mform->set_data(array('itemid'=>$itemid, 'userid'=>$userid, 'locked'=>$grade_item->locked, 'locktime'=>$grade_item->locktime));
}
if ($mform->is_cancelled()) {
redirect($returnurl);
// form processing
} else if ($data = $mform->get_data(false)) {
if (isset($data->feedback) && is_array($data->feedback)) {
$data->feedbackformat = $data->feedback['format'];
$data->feedback = $data->feedback['text'] ?? null;
}
$old_grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true); //might not exist yet
// fix no grade for scales
if (!isset($data->finalgrade) or $data->finalgrade == $data->oldgrade) {
$data->finalgrade = $old_grade_grade->finalgrade;
} else if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if ($data->finalgrade < 1) {
$data->finalgrade = NULL;
}
} else if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
$data->finalgrade = unformat_float($data->finalgrade);
} else {
//this should not happen
$data->finalgrade = $old_grade_grade->finalgrade;
}
// the overriding of feedback is tricky - we have to care about external items only
if (!property_exists($data, 'feedback') or $data->feedback == $data->oldfeedback) {
$data->feedback = $old_grade_grade->feedback;
$data->feedbackformat = $old_grade_grade->feedbackformat;
}
// update final grade or feedback
// when we set override grade the first time, it happens here
$grade_item->update_final_grade($data->userid, $data->finalgrade, 'editgrade', $data->feedback, $data->feedbackformat);
$grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true);
$grade_grade->grade_item =& $grade_item; // no db fetching
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:edit', $context)) {
// change overridden flag
if (!isset($data->overridden)) {
$data->overridden = 0; // checkbox unticked
}
$grade_grade->set_overridden($data->overridden);
}
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:hide', $context)) {
$hidden = empty($data->hidden) ? 0: $data->hidden;
$hiddenuntil = empty($data->hiddenuntil) ? 0: $data->hiddenuntil;
if ($grade_item->is_hidden()) {
if ($old_grade_grade->hidden == 1 and $hiddenuntil == 0) {
//nothing to do - grade was originally hidden, we want to keep it that way
} else {
$grade_grade->set_hidden($hiddenuntil);
}
} else {
if ($hiddenuntil) {
$grade_grade->set_hidden($hiddenuntil);
} else {
$grade_grade->set_hidden($hidden); // checkbox data might be undefined
}
}
}
if (isset($data->locked) and !$grade_item->is_locked()) {
if (($old_grade_grade->locked or $old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
//ignore data
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
//ignore data
} else {
$grade_grade->set_locktime($data->locktime); //set_lock may reset locktime
$grade_grade->set_locked($data->locked, false, true);
// reload grade in case it was regraded from activity
$grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true);
$grade_grade->grade_item =& $grade_item; // no db fetching
}
}
if (isset($data->excluded) and has_capability('moodle/grade:manage', $context)) {
$grade_grade->set_excluded($data->excluded);
}
// detect cases when we need to do full regrading
if ($old_grade_grade->excluded != $grade_grade->excluded) {
$parent = $grade_item->get_parent_category();
$parent->force_regrading();
} else if ($old_grade_grade->overridden != $grade_grade->overridden and empty($grade_grade->overridden)) { // only when unoverridding
$grade_item->force_regrading();
} else if ($old_grade_grade->locktime != $grade_grade->locktime) {
$grade_item->force_regrading();
}
redirect($returnurl);
}
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$strgradeedit = get_string('editgrade', 'grades');
$struser = get_string('user');
grade_build_nav(__FILE__, $strgradeedit, array('courseid' => $courseid));
/*********** BEGIN OUTPUT *************/
$PAGE->set_title($strgrades . ': ' . $strgraderreport . ': ' . $strgradeedit);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($strgradeedit);
echo $OUTPUT->box_start();
// Form if in edit or add modes
$mform->display();
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
die;
+216
View File
@@ -0,0 +1,216 @@
<?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/>.
/**
* A moodleform to allow the editing of a user's grade for a particular activity
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_grade_form extends moodleform {
function definition() {
global $CFG, $COURSE, $DB;
$mform =& $this->_form;
$grade_item = $this->_customdata['grade_item'];
$gpr = $this->_customdata['gpr'];
if ($grade_item->is_course_item()) {
$grade_category = null;
} else if ($grade_item->is_category_item()) {
$grade_category = $grade_item->get_item_category();
$grade_category = $grade_category->get_parent_category();
} else {
$grade_category = $grade_item->get_parent_category();
}
/// information fields
$mform->addElement('static', 'user', get_string('user'));
$mform->addElement('static', 'itemname', get_string('itemname', 'grades'));
$mform->addElement('checkbox', 'overridden', get_string('overridden', 'grades'));
$mform->addHelpButton('overridden', 'overridden', 'grades');
/// actual grade - numeric or scale
if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
// numeric grade
$mform->addElement('text', 'finalgrade', get_string('finalgrade', 'grades'));
$mform->setType('finalgrade', PARAM_RAW);
$mform->addHelpButton('finalgrade', 'finalgrade', 'grades');
$mform->disabledIf('finalgrade', 'overridden', 'notchecked');
} else if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
// scale grade
$scaleopt = array();
if (empty($grade_item->outcomeid)) {
$scaleopt[-1] = get_string('nograde');
} else {
$scaleopt[-1] = get_string('nooutcome', 'grades');
}
$i = 1;
if ($scale = $DB->get_record('scale', array('id' => $grade_item->scaleid))) {
foreach (explode(",", $scale->scale) as $option) {
$scaleopt[$i] = $option;
$i++;
}
}
$mform->addElement('select', 'finalgrade', get_string('finalgrade', 'grades'), $scaleopt);
$mform->addHelpButton('finalgrade', 'finalgrade', 'grades');
$mform->disabledIf('finalgrade', 'overridden', 'notchecked');
}
$mform->addElement('advcheckbox', 'excluded', get_string('excluded', 'grades'));
$mform->addHelpButton('excluded', 'excluded', 'grades');
/// hiding
/// advcheckbox is not compatible with disabledIf !!
$mform->addElement('checkbox', 'hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
/// locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
// Feedback format is automatically converted to html if user has enabled editor
$feedbackoptions = array('maxfiles'=>0, 'maxbytes'=>0); //TODO: no files here for now, if ever gets implemented use component 'grade' and filearea 'feedback'
$mform->addElement('editor', 'feedback', get_string('feedback', 'grades'), null, $feedbackoptions);
$mform->addHelpButton('feedback', 'feedback', 'grades');
$mform->setType('text', PARAM_RAW); // to be cleaned before display, no XSS risk
$mform->disabledIf('feedback', 'overridden');
// hidden params
$mform->addElement('hidden', 'oldgrade');
$mform->setType('oldgrade', PARAM_RAW);
$mform->addElement('hidden', 'oldfeedback');
$mform->setType('oldfeedback', PARAM_RAW);
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'itemid', 0);
$mform->setType('itemid', PARAM_INT);
$mform->addElement('hidden', 'userid', 0);
$mform->setType('userid', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
function definition_after_data() {
global $CFG, $COURSE, $DB;
$context = context_course::instance($COURSE->id);
$mform =& $this->_form;
$grade_item = $this->_customdata['grade_item'];
// fill in user name if user still exists
$userid = $mform->getElementValue('userid');
if ($user = $DB->get_record('user', array('id' => $userid))) {
$username = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'">'.fullname($user).'</a>';
$user_el =& $mform->getElement('user');
$user_el->setValue($username);
}
// add activity name + link
if ($grade_item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
$itemname = '<a href="'.$CFG->wwwroot.'/mod/'.$grade_item->itemmodule.'/view.php?id='.$cm->id.'">'.$grade_item->get_name().'</a>';
} else {
$itemname = $grade_item->get_name();
}
$itemname_el =& $mform->getElement('itemname');
$itemname_el->setValue($itemname);
// access control - disable not allowed elements
if (!has_capability('moodle/grade:manage', $context)) {
$mform->hardFreeze('excluded');
}
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
$mform->hardFreeze('hidden');
$mform->hardFreeze('hiddenuntil');
}
$old_grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$userid));
$gradeitemoverridable = $grade_item->is_overridable_item();
if (!$gradeitemoverridable) {
$mform->removeElement('overridden');
}
if ($grade_item->is_hidden()) {
$mform->hardFreeze('hidden');
}
if ($old_grade_grade->is_locked()) {
if ($grade_item->is_locked()) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
}
if ($gradeitemoverridable) {
$mform->hardFreeze('overridden');
}
$mform->hardFreeze('finalgrade');
$mform->hardFreeze('feedback');
} else {
if (empty($old_grade_grade->id)) {
$old_grade_grade->locked = $grade_item->locked;
$old_grade_grade->locktime = $grade_item->locktime;
}
if (($old_grade_grade->locked or $old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
}
}
}
}
+286
View File
@@ -0,0 +1,286 @@
<?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/>.
/**
* The Gradebook setup page.
*
* @package core_grades
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('NO_OUTPUT_BUFFERING', true); // The progress bar may be used here.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences
require_once $CFG->dirroot.'/grade/edit/tree/lib.php';
$courseid = required_param('id', PARAM_INT);
$action = optional_param('action', 0, PARAM_ALPHA);
$eid = optional_param('eid', 0, PARAM_ALPHANUM);
$weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid));
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
/// Make sure they can even access this course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$PAGE->requires->js_call_amd('core_grades/edittree_index', 'init', [$courseid, $USER->id]);
$PAGE->requires->js_call_amd('core_grades/gradebooksetup_forms', 'init');
$decsep = get_string('decsep', 'langconfig');
// This setting indicates if we should use algorithm prior to MDL-49257 fix for calculating extra credit weights.
$gradebookcalculationfreeze = (int) get_config('core', 'gradebook_calculations_freeze_' . $courseid);
$oldextracreditcalculation = $gradebookcalculationfreeze && ($gradebookcalculationfreeze <= 20150619);
$PAGE->requires->js_call_amd('core_grades/edittree_weights', 'init', [$decsep, $oldextracreditcalculation]);
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
$returnurl = $gpr->get_return_url(null);
// get the grading tree object
// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
$gtree = new grade_tree($courseid, false, false);
if (empty($eid)) {
$element = null;
$object = null;
} else {
if (!$element = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object = $element['object'];
}
$switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition);
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$moving = false;
$movingeid = false;
if ($action == 'moveselect') {
if ($eid and confirm_sesskey()) {
$movingeid = $eid;
$moving=true;
}
}
$gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr);
switch ($action) {
case 'duplicate':
if ($eid and confirm_sesskey()) {
if (!$el = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object->duplicate();
redirect($returnurl);
}
break;
case 'delete':
if ($eid && confirm_sesskey()) {
if (!$gradeedittree->element_deletable($element)) {
// no deleting of external activities - they would be recreated anyway!
// exception is activity without grading or misconfigured activities
break;
}
$confirm = optional_param('confirm', 0, PARAM_BOOL);
if ($confirm) {
$object->delete('grade/report/grader/category');
redirect($returnurl);
}
}
break;
case 'autosort':
//TODO: implement autosorting based on order of mods on course page, categories first, manual items last
break;
case 'move':
if ($eid and confirm_sesskey()) {
$moveafter = required_param('moveafter', PARAM_ALPHANUM);
$first = optional_param('first', false, PARAM_BOOL); // If First is set to 1, it means the target is the first child of the category $moveafter
if(!$after_el = $gtree->locate_element($moveafter)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$after = $after_el['object'];
$sortorder = $after->get_sortorder();
if (!$first) {
$parent = $after->get_parent_category();
$object->set_parent($parent->id);
} else {
$object->set_parent($after->id);
}
$object->move_after_sortorder($sortorder);
redirect($returnurl);
}
break;
default:
break;
}
// If we go straight to the db to update an element we need to recreate the tree as
// $gradeedittree has already been constructed.
// Ideally we could do the updates through $gradeedittree to avoid recreating it.
$recreatetree = false;
if ($data = data_submitted() and confirm_sesskey()) {
// Perform bulk actions first
if (!empty($data->bulkmove)) {
$elements = array();
foreach ($data as $key => $value) {
if (preg_match('/select_(ig[0-9]*)/', $key, $matches)) {
$elements[] = $matches[1];
}
}
$gradeedittree->move_elements($elements, $returnurl);
}
// Update weights (extra credits) on categories and items.
foreach ($data as $key => $value) {
if (preg_match('/^weight_([0-9]+)$/', $key, $matches)) {
$aid = $matches[1];
$value = unformat_float($value);
$value = clean_param($value, PARAM_FLOAT);
$grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
// Convert weight to aggregation coef2.
$aggcoef = $grade_item->get_coefstring();
if ($aggcoef == 'aggregationcoefextraweightsum') {
// The field 'weight' should only be sent when the checkbox 'weighoverride' is checked,
// so there is not need to set weightoverride here, it is done below.
$value = $value / 100.0;
$grade_item->aggregationcoef2 = $value;
} else if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoefextraweight') {
$grade_item->aggregationcoef = $value;
}
$grade_item->update();
$recreatetree = true;
// Grade item checkbox inputs.
} elseif (preg_match('/^(weightoverride)_([0-9]+)$/', $key, $matches)) {
$param = $matches[1];
$aid = $matches[2];
$value = clean_param($value, PARAM_BOOL);
$grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
$grade_item->$param = $value;
$grade_item->update();
$recreatetree = true;
}
}
}
$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
/**
* Callback function to adjust the URL if weights changed after the
* regrade.
*
* @param int $courseid The course ID
* @param array $originalweights The weights before the regrade
* @param int $weightsadjusted Whether weights have been adjusted
* @return moodle_url A URL to redirect to after regrading when a progress bar is displayed.
*/
$grade_edit_tree_index_checkweights = function() use ($courseid, $originalweights, &$weightsadjusted) {
global $PAGE;
$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
if (array_diff($originalweights, $alteredweights)) {
$weightsadjusted = 1;
return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted));
}
return $PAGE->url;
};
if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) {
$recreatetree = true;
}
$actionbar = new \core_grades\output\gradebook_setup_action_bar($context);
print_grade_page_head($courseid, 'settings', 'setup', false,
false, false, true, null, null, null, $actionbar);
// Print Table of categories and items
echo $OUTPUT->box_start('gradetreebox generalbox');
// Did we update something in the db and thus invalidate $gradeedittree?
if ($recreatetree) {
$gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr);
}
$tpldata = (object) [
'actionurl' => $returnurl,
'sesskey' => sesskey(),
'movingmodeenabled' => $moving,
'courseid' => $courseid
];
// Check to see if we have a normalisation message to send.
if ($weightsadjusted) {
$notification = new \core\output\notification(get_string('weightsadjusted', 'grades'), \core\output\notification::NOTIFY_INFO);
$tpldata->notification = $notification->export_for_template($OUTPUT);
}
$tpldata->table = html_writer::table($gradeedittree->table);
// If not in moving mode and there is more than one grade category, then initialise the bulk action module.
if (!$moving && count($gradeedittree->categories) > 1) {
$PAGE->requires->js_call_amd('core_grades/bulkactions/edit/tree/bulk_actions', 'init', [$courseid]);
}
$footercontent = $OUTPUT->render_from_template('core_grades/edit_tree_sticky_footer', $tpldata);
$stickyfooter = new core\output\sticky_footer($footercontent);
$tpldata->stickyfooter = $OUTPUT->render($stickyfooter);
echo $OUTPUT->render_from_template('core_grades/edit_tree', $tpldata);
echo $OUTPUT->box_end();
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['gradetreeform']);
echo $OUTPUT->footer();
die;
+215
View File
@@ -0,0 +1,215 @@
<?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/>.
/**
* Edit the grade options for an individual grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_item;
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'item_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/item.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$heading = get_string('itemsedit', 'grades');
if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
// redirect if outcomeid present
if (!empty($grade_item->outcomeid) && !empty($CFG->enableoutcomes)) {
$url = new moodle_url('/grade/edit/tree/outcomeitem.php', ['id' => $id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
$grade_category = $grade_item->get_item_category();
$url = new moodle_url('/grade/edit/tree/category.php', ['id' => $grade_category->id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
$item = $grade_item->get_record_data();
$parent_category = $grade_item->get_parent_category();
$item->parentcategory = $parent_category->id;
} else {
$heading = get_string('newitem', 'grades');
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
$item = $grade_item->get_record_data();
$parent_category = grade_category::fetch_course_category($courseid);
$item->parentcategory = $parent_category->id;
}
$decimalpoints = $grade_item->get_decimals();
if ($item->hidden > 1) {
$item->hiddenuntil = $item->hidden;
$item->hidden = 0;
} else {
$item->hiddenuntil = 0;
}
$item->locked = !empty($item->locked);
$item->grademax = format_float($item->grademax, $decimalpoints);
$item->grademin = format_float($item->grademin, $decimalpoints);
$item->gradepass = format_float($item->gradepass, $decimalpoints);
$item->multfactor = format_float($item->multfactor, 4);
$item->plusfactor = format_float($item->plusfactor, 4);
if ($parent_category->aggregation == GRADE_AGGREGATE_SUM or $parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$item->aggregationcoef = $item->aggregationcoef == 0 ? 0 : 1;
} else {
$item->aggregationcoef = format_float($item->aggregationcoef, 4);
}
if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0);
}
$item->cancontrolvisibility = $grade_item->can_control_visibility();
$mform = new edit_item_form(null, array('current'=>$item, 'gpr'=>$gpr));
$simpleform = new add_item(null, ['itemid' => $grade_item->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
// This is a new item, and the category chosen is different than the default category.
if (empty($grade_item->id) && isset($data->parentcategory) && $parent_category->id != $data->parentcategory) {
$parent_category = grade_category::fetch(array('id' => $data->parentcategory));
}
// If unset, give the aggregation values a default based on parent aggregation method.
$defaults = grade_category::get_default_aggregation_coefficient_values($parent_category->aggregation);
if (!isset($data->aggregationcoef) || $data->aggregationcoef == '') {
$data->aggregationcoef = $defaults['aggregationcoef'];
}
if (!isset($data->weightoverride)) {
$data->weightoverride = $defaults['weightoverride'];
}
if (!isset($data->gradepass) || $data->gradepass == '') {
$data->gradepass = 0;
}
if (!isset($data->grademin) || $data->grademin == '') {
$data->grademin = 0;
}
$hide = empty($data->hiddenuntil) ? 0 : $data->hiddenuntil;
if (!$hide) {
$hide = empty($data->hidden) ? 0 : $data->hidden;
}
unset($data->hidden);
unset($data->hiddenuntil);
$locked = empty($data->locked) ? 0: $data->locked;
$locktime = empty($data->locktime) ? 0: $data->locktime;
unset($data->locked);
unset($data->locktime);
$convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef', 'aggregationcoef2');
foreach ($convert as $param) {
if (property_exists($data, $param)) {
$data->$param = unformat_float($data->$param);
}
}
if (isset($data->aggregationcoef2) && $parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$data->aggregationcoef2 = $data->aggregationcoef2 / 100.0;
} else {
$data->aggregationcoef2 = $defaults['aggregationcoef2'];
}
$gradeitem = new grade_item(array('id' => $id, 'courseid' => $courseid));
$oldmin = $gradeitem->grademin;
$oldmax = $gradeitem->grademax;
grade_item::set_properties($gradeitem, $data);
$gradeitem->outcomeid = null;
// Handle null decimals value
if (!property_exists($data, 'decimals') or $data->decimals < 0) {
$gradeitem->decimals = null;
}
if (empty($gradeitem->id)) {
$gradeitem->itemtype = 'manual'; // All new items to be manual only.
$gradeitem->insert();
// set parent if needed
if (isset($data->parentcategory)) {
$gradeitem->set_parent($data->parentcategory, false);
}
} else {
$gradeitem->update();
if (!empty($data->rescalegrades) && $data->rescalegrades == 'yes') {
$newmin = $gradeitem->grademin;
$newmax = $gradeitem->grademax;
$gradeitem->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, 'gradebook');
}
}
if ($item->cancontrolvisibility) {
// Update hiding flag.
$gradeitem->set_hidden($hide, true);
}
$gradeitem->set_locktime($locktime); // Locktime first - it might be removed when unlocking.
$gradeitem->set_locked($locked, false, true);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
$mform->display();
echo $OUTPUT->footer();
+473
View File
@@ -0,0 +1,473 @@
<?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/>.
/**
* A moodleform allowing the editing of the grade options for an individual grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_item_form extends moodleform {
private $displayoptions;
function definition() {
global $COURSE, $CFG, $DB;
$mform =& $this->_form;
$item = $this->_customdata['current'];
/// visible elements
$mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
$mform->addElement('text', 'itemname', get_string('itemname', 'grades'));
$mform->setType('itemname', PARAM_TEXT);
$mform->addElement('text', 'iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('iteminfo', 'iteminfo', 'grades');
$mform->setType('iteminfo', PARAM_TEXT);
$mform->addElement('text', 'idnumber', get_string('idnumbermod'));
$mform->addHelpButton('idnumber', 'idnumbermod');
$mform->setType('idnumber', PARAM_RAW);
if (!empty($item->id)) {
$gradeitem = new grade_item(array('id' => $item->id, 'courseid' => $item->courseid));
// If grades exist set a message so the user knows why they can not alter the grade type or scale.
// We could never change the grade type for external items, so only need to show this for manual grade items.
if ($gradeitem->has_grades() && !$gradeitem->is_external_item()) {
// Set a message so the user knows why they can not alter the grade type or scale.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$gradesexistmsg = get_string('modgradecantchangegradetyporscalemsg', 'grades');
} else {
$gradesexistmsg = get_string('modgradecantchangegradetypemsg', 'grades');
}
$gradesexisthtml = '<div class=\'alert\'>' . $gradesexistmsg . '</div>';
$mform->addElement('static', 'gradesexistmsg', '', $gradesexisthtml);
}
}
// Manual grade items cannot have grade type GRADE_TYPE_NONE.
$options = array(GRADE_TYPE_VALUE => get_string('typevalue', 'grades'),
GRADE_TYPE_SCALE => get_string('typescale', 'grades'),
GRADE_TYPE_TEXT => get_string('typetext', 'grades'));
$mform->addElement('select', 'gradetype', get_string('gradetype', 'grades'), $options);
$mform->addHelpButton('gradetype', 'gradetype', 'grades');
$mform->setDefault('gradetype', GRADE_TYPE_VALUE);
//$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
$options = array(0=>get_string('usenoscale', 'grades'));
if ($scales = grade_scale::fetch_all_local($COURSE->id)) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
if ($scales = grade_scale::fetch_all_global()) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
// ugly BC hack - it was possible to use custom scale from other courses :-(
if (!empty($item->scaleid) and !isset($options[$item->scaleid])) {
if ($scale = grade_scale::fetch(array('id'=>$item->scaleid))) {
$options[$scale->id] = $scale->get_name().get_string('incorrectcustomscale', 'grades');
}
}
$mform->addElement('select', 'scaleid', get_string('scale'), $options);
$mform->addHelpButton('scaleid', 'typescale', 'grades');
$mform->disabledIf('scaleid', 'gradetype', 'noteq', GRADE_TYPE_SCALE);
$choices = array();
$choices[''] = get_string('choose');
$choices['no'] = get_string('no');
$choices['yes'] = get_string('yes');
$mform->addElement('select', 'rescalegrades', get_string('modgraderescalegrades', 'grades'), $choices);
$mform->addHelpButton('rescalegrades', 'modgraderescalegrades', 'grades');
$mform->disabledIf('rescalegrades', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->addElement('float', 'grademax', get_string('grademax', 'grades'));
$mform->addHelpButton('grademax', 'grademax', 'grades');
$mform->disabledIf('grademax', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
if ((bool) get_config('moodle', 'grade_report_showmin')) {
$mform->addElement('float', 'grademin', get_string('grademin', 'grades'));
$mform->addHelpButton('grademin', 'grademin', 'grades');
$mform->disabledIf('grademin', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
}
$mform->addElement('float', 'gradepass', get_string('gradepass', 'grades'));
$mform->addHelpButton('gradepass', 'gradepass', 'grades');
$mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'multfactor', get_string('multfactor', 'grades'));
$mform->addHelpButton('multfactor', 'multfactor', 'grades');
$mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'plusfactor', get_string('plusfactor', 'grades'));
$mform->addHelpButton('plusfactor', 'plusfactor', 'grades');
$mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT);
/// grade display prefs
$default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
$options = array(GRADE_DISPLAY_TYPE_DEFAULT => get_string('default', 'grades'),
GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades')
);
asort($options);
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'display', get_string('gradedisplaytype', 'grades'), $options);
$mform->addHelpButton('display', 'gradedisplaytype', 'grades');
$mform->disabledIf('display', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
$options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'decimals', get_string('decimalpoints', 'grades'), $options);
$mform->addHelpButton('decimals', 'decimalpoints', 'grades');
$mform->setDefault('decimals', -1);
$mform->disabledIf('decimals', 'display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
$mform->disabledIf('decimals', 'display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
}
$mform->disabledIf('decimals', 'gradetype', 'eq', GRADE_TYPE_TEXT);
/// hiding
if ($item->cancontrolvisibility) {
$mform->addElement('advcheckbox', 'hidden', get_string('hidden', 'grades'), '', [], [0, 1]);
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
} else {
$mform->addElement('static', 'hidden', get_string('hidden', 'grades'),
get_string('componentcontrolsvisibility', 'grades'));
// Unset hidden to avoid data override.
unset($item->hidden);
}
$mform->addHelpButton('hidden', 'hidden', 'grades');
/// locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->addElement('advcheckbox', 'weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('weightoverride', 'weightoverride', 'grades');
$mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('aggregationcoef2', 'weight', 'grades');
$mform->disabledIf('aggregationcoef2', 'weightoverride');
$mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$options = array();
$coefstring = '';
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options);
}
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
$mform->addElement('hidden', 'itemtype', 'manual'); // all new items are manual only
$mform->setType('itemtype', PARAM_ALPHA);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
//-------------------------------------------------------------------------------
$this->set_data($item);
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
if ($id = $mform->getElementValue('id')) {
$gradeitem = grade_item::fetch(array('id' => $id));
$parentcategory = $gradeitem->get_parent_category();
} else {
// If we do not have an id, we are creating a new grade item.
$gradeitem = new grade_item(array('courseid' => $COURSE->id, 'itemtype' => 'manual'), false);
// Assign the course category to this grade item.
$parentcategory = grade_category::fetch_course_category($COURSE->id);
$gradeitem->parent_category = $parentcategory;
}
if (!$gradeitem->is_raw_used()) {
$mform->removeElement('plusfactor');
$mform->removeElement('multfactor');
}
if ($gradeitem->is_outcome_item()) {
// We have to prevent incompatible modifications of outcomes if outcomes disabled.
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
$mform->removeElement('gradetype');
$mform->removeElement('display');
$mform->removeElement('decimals');
$mform->hardFreeze('scaleid');
} else {
if ($gradeitem->is_external_item()) {
// Following items are set up from modules and should not be overrided by user.
if ($mform->elementExists('grademin')) {
// The site setting grade_report_showmin may have prevented grademin being added to the form.
$mform->hardFreeze('grademin');
}
$mform->hardFreeze('itemname,gradetype,grademax,scaleid');
if ($gradeitem->itemnumber == 0) {
// The idnumber of grade itemnumber 0 is synced with course_modules.
$mform->hardFreeze('idnumber');
}
// For external items we can not change the grade type, even if no grades exist, so if it is set to
// scale, then remove the grademax and grademin fields from the form - no point displaying them.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
} else { // Not using scale, so remove it.
$mform->removeElement('scaleid');
}
// Always remove the rescale grades element if it's an external item.
$mform->removeElement('rescalegrades');
} else if ($gradeitem->has_grades()) {
// Can't change the grade type or the scale if there are grades.
$mform->hardFreeze('gradetype, scaleid');
// If we are using scales then remove the unnecessary rescale and grade fields.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('rescalegrades');
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
} else { // Remove the scale field.
$mform->removeElement('scaleid');
// Set the maximum grade to disabled unless a grade is chosen.
$mform->disabledIf('grademax', 'rescalegrades', 'eq', '');
}
} else {
// Remove the rescale element if there are no grades.
$mform->removeElement('rescalegrades');
}
}
// If we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!!
if ($id && $mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
$parentcategory->apply_forced_settings();
if (!$parentcategory->is_aggregationcoef_used()) {
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
$coefstring = $gradeitem->get_coefstring();
if ($coefstring !== '') {
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// The advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$element =& $mform->createElement('checkbox', 'aggregationcoef', get_string($coefstring, 'grades'));
} else {
$element =& $mform->createElement('text', 'aggregationcoef', get_string($coefstring, 'grades'));
}
if ($mform->elementExists('parentcategory')) {
$mform->insertElementBefore($element, 'parentcategory');
} else {
$mform->insertElementBefore($element, 'id');
}
$mform->addHelpButton('aggregationcoef', $coefstring, 'grades');
}
$mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $parentcategory->id);
}
// Remove fields used by natural weighting if the parent category is not using natural weighting.
// Or if the item is a scale and scales are not used in aggregation.
if ($parentcategory->aggregation != GRADE_AGGREGATE_SUM
|| (empty($CFG->grade_includescalesinaggregation) && $gradeitem->gradetype == GRADE_TYPE_SCALE)) {
if ($mform->elementExists('weightoverride')) {
$mform->removeElement('weightoverride');
}
if ($mform->elementExists('aggregationcoef2')) {
$mform->removeElement('aggregationcoef2');
}
}
if ($category = $gradeitem->get_item_category()) {
if ($category->aggregation == GRADE_AGGREGATE_SUM) {
if ($mform->elementExists('gradetype')) {
$mform->hardFreeze('gradetype');
}
if ($mform->elementExists('grademin')) {
$mform->hardFreeze('grademin');
}
if ($mform->elementExists('grademax')) {
$mform->hardFreeze('grademax');
}
if ($mform->elementExists('scaleid')) {
$mform->removeElement('scaleid');
}
}
}
// no parent header for course category
if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
}
/// perform extra validation before submission
function validation($data, $files) {
global $COURSE;
$grade_item = false;
if ($data['id']) {
$grade_item = new grade_item(array('id' => $data['id'], 'courseid' => $data['courseid']));
}
$errors = parent::validation($data, $files);
if (array_key_exists('idnumber', $data)) {
if ($grade_item) {
if ($grade_item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
} else {
$cm = null;
}
} else {
$grade_item = null;
$cm = null;
}
if (!grade_verify_idnumber($data['idnumber'], $COURSE->id, $grade_item, $cm)) {
$errors['idnumber'] = get_string('idnumbertaken');
}
}
if (array_key_exists('gradetype', $data) and $data['gradetype'] == GRADE_TYPE_SCALE) {
if (empty($data['scaleid'])) {
$errors['scaleid'] = get_string('missingscale', 'grades');
}
}
// We need to make all the validations related with grademax and grademin
// with them being correct floats, keeping the originals unmodified for
// later validations / showing the form back...
// TODO: Note that once MDL-73994 is fixed we'll have to re-visit this and
// adapt the code below to the new values arriving here, without forgetting
// the special case of empties and nulls.
$grademax = isset($data['grademax']) ? unformat_float($data['grademax']) : null;
$grademin = isset($data['grademin']) ? unformat_float($data['grademin']) : null;
if (!is_null($grademin) and !is_null($grademax)) {
if ($grademax == $grademin or $grademax < $grademin) {
$errors['grademin'] = get_string('incorrectminmax', 'grades');
$errors['grademax'] = get_string('incorrectminmax', 'grades');
}
}
// We do not want the user to be able to change the grade type or scale for this item if grades exist.
if ($grade_item && $grade_item->has_grades()) {
// Check that grade type is set - should never not be set unless form has been modified.
if (!isset($data['gradetype'])) {
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
} else if ($data['gradetype'] !== $grade_item->gradetype) { // Check if we are changing the grade type.
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
} else if ($data['gradetype'] == GRADE_TYPE_SCALE) {
// Check if we are changing the scale - can't do this when grades exist.
if (isset($data['scaleid']) && ($data['scaleid'] !== $grade_item->scaleid)) {
$errors['scaleid'] = get_string('modgradecantchangescale', 'grades');
}
}
}
if ($grade_item) {
if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
if ((((bool) get_config('moodle', 'grade_report_showmin')) &&
grade_floats_different($grademin, $grade_item->grademin)) ||
grade_floats_different($grademax, $grade_item->grademax)) {
if ($grade_item->has_grades() && empty($data['rescalegrades'])) {
$errors['rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
}
}
}
}
return $errors;
}
}
File diff suppressed because it is too large Load Diff
+254
View File
@@ -0,0 +1,254 @@
<?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/>.
/**
* A page to create or edit outcome grade items
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_outcome;
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'outcomeitem_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/outcomeitem.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$mform = new edit_outcomeitem_form(null, array('gpr'=>$gpr));
if ($mform->is_cancelled() || empty($CFG->enableoutcomes)) {
redirect($returnurl);
}
$heading = get_string('outcomeitemsedit', 'grades');
if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
// redirect if outcomeid present
if (empty($grade_item->outcomeid)) {
$url = new moodle_url('/grade/edit/tree/item.php', ['id' => $id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
$item = $grade_item->get_record_data();
$parent_category = $grade_item->get_parent_category();
$item->parentcategory = $parent_category->id;
if ($item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($item->itemmodule, $item->iteminstance, $item->courseid);
$item->cmid = $cm->id;
} else {
$item->cmid = 0;
}
} else {
$heading = get_string('newoutcomeitem', 'grades');
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
$item = $grade_item->get_record_data();
$item->cmid = 0;
$parent_category = grade_category::fetch_course_category($courseid);
$item->parentcategory = $parent_category->id;
}
$decimalpoints = $grade_item->get_decimals();
if ($item->hidden > 1) {
$item->hiddenuntil = $item->hidden;
$item->hidden = 0;
} else {
$item->hiddenuntil = 0;
}
$item->locked = !empty($item->locked);
$item->gradepass = format_float($item->gradepass, $decimalpoints);
if (empty($parent_category)) {
$item->aggregationcoef = 0;
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$item->aggregationcoef = $item->aggregationcoef > 0 ? 1 : 0;
$item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0);
} else {
$item->aggregationcoef = format_float($item->aggregationcoef, 4);
}
$mform->set_data($item);
$simpleform = new add_outcome(null, ['itemid' => $grade_item->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($data = $mform->get_data()) {
// This is a new item, and the category chosen is different than the default category.
if (empty($grade_item->id) && isset($data->parentcategory) && $parent_category->id != $data->parentcategory) {
$parent_category = grade_category::fetch(array('id' => $data->parentcategory));
}
// If unset, give the aggregation values a default based on parent aggregation method.
$defaults = grade_category::get_default_aggregation_coefficient_values($parent_category->aggregation);
if (!isset($data->aggregationcoef) || $data->aggregationcoef == '') {
$data->aggregationcoef = $defaults['aggregationcoef'];
}
if (!isset($data->weightoverride)) {
$data->weightoverride = $defaults['weightoverride'];
}
if (property_exists($data, 'calculation')) {
$data->calculation = grade_item::normalize_formula($data->calculation, $course->id);
}
$hidden = empty($data->hidden) ? 0: $data->hidden;
$hiddenuntil = empty($data->hiddenuntil) ? 0: $data->hiddenuntil;
unset($data->hidden);
unset($data->hiddenuntil);
$locked = empty($data->locked) ? 0: $data->locked;
$locktime = empty($data->locktime) ? 0: $data->locktime;
unset($data->locked);
unset($data->locktime);
$convert = array('gradepass', 'aggregationcoef', 'aggregationcoef2');
foreach ($convert as $param) {
if (property_exists($data, $param)) {
$data->$param = unformat_float($data->$param);
}
}
if (isset($data->aggregationcoef2) && $parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$data->aggregationcoef2 = $data->aggregationcoef2 / 100.0;
} else {
$data->aggregationcoef2 = $defaults['aggregationcoef2'];
}
$grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
grade_item::set_properties($grade_item, $data);
// fix activity links
if (empty($data->cmid)) {
// manual item
$grade_item->itemtype = 'manual';
$grade_item->itemmodule = null;
$grade_item->iteminstance = null;
$grade_item->itemnumber = 0;
} else {
$params = array($data->cmid);
$module = $DB->get_record_sql("SELECT cm.*, m.name as modname
FROM {modules} m, {course_modules} cm
WHERE cm.id = ? AND cm.module = m.id ", $params);
$grade_item->itemtype = 'mod';
$grade_item->itemmodule = $module->modname;
$grade_item->iteminstance = $module->instance;
if ($items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$grade_item->itemmodule,
'iteminstance'=>$grade_item->iteminstance, 'courseid'=>$COURSE->id))) {
if (!empty($grade_item->id) and in_array($grade_item, $items)) {
//no change needed
} else {
$max = 999;
foreach($items as $item) {
if (empty($item->outcomeid)) {
continue;
}
if ($item->itemnumber > $max) {
$max = $item->itemnumber;
}
}
$grade_item->itemnumber = $max + 1;
}
} else {
$grade_item->itemnumber = 1000;
}
}
// fix scale used
$outcome = grade_outcome::fetch(array('id'=>$data->outcomeid));
$grade_item->gradetype = GRADE_TYPE_SCALE;
$grade_item->scaleid = $outcome->scaleid; //TODO: we might recalculate existing outcome grades when changing scale
if (empty($grade_item->id)) {
$grade_item->insert();
// move next to activity if adding linked outcome
if ($grade_item->itemtype == 'mod') {
if ($item = grade_item::fetch(array('itemtype'=>'mod', 'itemmodule'=>$grade_item->itemmodule,
'iteminstance'=>$grade_item->iteminstance, 'itemnumber'=>0, 'courseid'=>$COURSE->id))) {
$grade_item->set_parent($item->categoryid);
$grade_item->move_after_sortorder($item->sortorder);
}
} else {
// set parent if needed
if (isset($data->parentcategory)) {
$grade_item->set_parent($data->parentcategory, false);
}
}
} else {
$grade_item->update();
}
// update hiding flag
if ($hiddenuntil) {
$grade_item->set_hidden($hiddenuntil, false);
} else {
$grade_item->set_hidden($hidden, false);
}
$grade_item->set_locktime($locktime); // locktime first - it might be removed when unlocking
$grade_item->set_locked($locked, false, true);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
if (!grade_outcome::fetch_all_available($COURSE->id)) {
echo $OUTPUT->confirm(get_string('nooutcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$courseid, $returnurl);
echo $OUTPUT->footer();
die();
}
$mform->display();
echo $OUTPUT->footer();
+266
View File
@@ -0,0 +1,266 @@
<?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/>.
/**
* A moodleform to allow the creation and editing of outcome grade items
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_outcomeitem_form extends moodleform {
function definition() {
global $COURSE, $CFG;
$mform =& $this->_form;
/// visible elements
$mform->addElement('header', 'general', get_string('gradeoutcomeitem', 'grades'));
$mform->addElement('text', 'itemname', get_string('itemname', 'grades'));
$mform->addRule('itemname', get_string('required'), 'required', null, 'client');
$mform->setType('itemname', PARAM_TEXT);
$mform->addElement('text', 'iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('iteminfo', 'iteminfo', 'grades');
$mform->setType('iteminfo', PARAM_TEXT);
$mform->addElement('text', 'idnumber', get_string('idnumbermod'));
$mform->addHelpButton('idnumber', 'idnumbermod');
$mform->setType('idnumber', PARAM_RAW);
// allow setting of outcomes on module items too
$options = array();
if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) {
foreach ($outcomes as $outcome) {
$options[$outcome->id] = $outcome->get_name();
}
}
$mform->addElement('selectwithlink', 'outcomeid', get_string('outcome', 'grades'), $options, null,
array('link' => $CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$COURSE->id, 'label' => get_string('outcomeassigntocourse', 'grades')));
$mform->addHelpButton('outcomeid', 'outcome', 'grades');
$mform->addRule('outcomeid', get_string('required'), 'required');
$options = array(0=>get_string('none'));
if ($coursemods = get_course_mods($COURSE->id)) {
foreach ($coursemods as $coursemod) {
if ($mod = get_coursemodule_from_id($coursemod->modname, $coursemod->id)) {
$options[$coursemod->id] = format_string($mod->name);
}
}
}
$mform->addElement('select', 'cmid', get_string('linkedactivity', 'grades'), $options);
$mform->addHelpButton('cmid', 'linkedactivity', 'grades');
$mform->setDefault('cmid', 0);
/// hiding
/// advcheckbox is not compatible with disabledIf !!
$mform->addElement('checkbox', 'hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
//locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->addElement('advcheckbox', 'weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('weightoverride', 'weightoverride', 'grades');
$mform->addElement('text', 'aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('aggregationcoef2', 'weight', 'grades');
$mform->setType('aggregationcoef2', PARAM_RAW);
$mform->disabledIf('aggregationcoef2', 'weightoverride');
$options = array();
$default = '';
$coefstring = '';
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
if ($cat->is_course_category()) {
$default = $cat->id;
}
if ($cat->is_aggregationcoef_used()) {
if ($cat->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefweight') ? 'aggregationcoefweight' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextrasum') ? 'aggregationcoefextrasum' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextraweight') ? 'aggregationcoefextraweight' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_SUM) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextrasum') ? 'aggregationcoefextrasum' : 'aggregationcoef';
} else {
$coefstring = 'aggregationcoef';
}
} else {
$mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $cat->id);
}
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options);
$mform->disabledIf('parentcategory', 'cmid', 'noteq', 0);
}
if ($coefstring !== '') {
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$mform->addElement('checkbox', 'aggregationcoef', get_string($coefstring, 'grades'));
} else {
$mform->addElement('text', 'aggregationcoef', get_string($coefstring, 'grades'));
}
$mform->addHelpButton('aggregationcoef', $coefstring, 'grades');
}
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
if ($id = $mform->getElementValue('id')) {
$grade_item = grade_item::fetch(array('id'=>$id));
//remove the aggregation coef element if not needed
if ($grade_item->is_course_item()) {
if ($mform->elementExists('parentcategory')) {
$mform->removeElement('parentcategory');
}
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
// if we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!!
if ($mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
if ($grade_item->is_category_item()) {
$category = $grade_item->get_item_category();
$parent_category = $category->get_parent_category();
} else {
$parent_category = $grade_item->get_parent_category();
}
$parent_category->apply_forced_settings();
if (!$parent_category->is_aggregationcoef_used() || !$parent_category->aggregateoutcomes) {
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
//fix label if needed
$agg_el =& $mform->getElement('aggregationcoef');
$aggcoef = '';
if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
$aggcoef = 'aggregationcoefweight';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$aggcoef = 'aggregationcoefextrasum';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
$aggcoef = 'aggregationcoefextraweight';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$aggcoef = 'aggregationcoefextrasum';
}
if ($aggcoef !== '') {
$agg_el->setLabel(get_string($aggcoef, 'grades'));
$mform->addHelpButton('aggregationcoef', $aggcoef, 'grades');
}
}
// Remove the natural weighting fields for other aggregations,
// or when the category does not aggregate outcomes.
if ($parent_category->aggregation != GRADE_AGGREGATE_SUM ||
!$parent_category->aggregateoutcomes) {
if ($mform->elementExists('weightoverride')) {
$mform->removeElement('weightoverride');
}
if ($mform->elementExists('aggregationcoef2')) {
$mform->removeElement('aggregationcoef2');
}
}
}
}
// no parent header for course category
if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
}
/// perform extra validation before submission
function validation($data, $files) {
global $COURSE;
$errors = parent::validation($data, $files);
if (array_key_exists('idnumber', $data)) {
if ($data['id']) {
$grade_item = new grade_item(array('id'=>$data['id'], 'courseid'=>$data['courseid']));
} else {
$grade_item = null;
}
if (!grade_verify_idnumber($data['idnumber'], $COURSE->id, $grade_item, null)) {
$errors['idnumber'] = get_string('idnumbertaken');
}
}
return $errors;
}
}