diff --git a/grade/grading/form/lib.php b/grade/grading/form/lib.php
index aa076c9aab8..ba14e8002d0 100644
--- a/grade/grading/form/lib.php
+++ b/grade/grading/form/lib.php
@@ -264,6 +264,30 @@ abstract class gradingform_controller {
}
}
+ /**
+ * Saves non-js data and returns the gradebook grade
+ */
+ abstract public function save_and_get_grade($itemid, $formdata);
+
+ /**
+ * Returns html for form element
+ */
+ abstract public function to_html($gradingformelement);
+
+ /**
+ *
+ */
+ public function default_validation_error_message() {
+ return '';
+ }
+
+ /**
+ *
+ */
+ public function validate_grading_element($elementvalue, $itemid) {
+ return true;
+ }
+
////////////////////////////////////////////////////////////////////////////
diff --git a/grade/grading/form/rubric/lib.php b/grade/grading/form/rubric/lib.php
index f34bad57543..fd79691f57f 100644
--- a/grade/grading/form/rubric/lib.php
+++ b/grade/grading/form/rubric/lib.php
@@ -226,6 +226,41 @@ class gradingform_rubric_controller extends gradingform_controller {
return $properties;
}
+ /**
+ * Saves non-js data and returns the gradebook grade
+ */
+ public function save_and_get_grade($itemid, $formdata) {
+ // TODO: this function is a patch at the moment!
+ if (is_array($formdata) && array_key_exists('grade', $formdata)) {
+ return $formdata['grade'];
+ }
+ return -1;
+ }
+
+ /**
+ * Returns html for form element
+ */
+ public function to_html($gradingformelement) {
+ // TODO: this function is a patch at the moment!
+
+ //global $PAGE, $USER;
+ //$gradingrenderer = $this->prepare_renderer($PAGE);
+ $output = '';
+ $elementname = $gradingformelement->getName();
+ $elementvalue = $gradingformelement->getValue();
+ $submissionid = $gradingformelement->get_grading_attribute('submissionid');
+ $output .= "assessing submission $submissionid
";
+ $output .= html_writer::empty_tag('input', array('type' => 'text', 'name' => $elementname.'[grade]', 'size' => '20', 'value' => $elementvalue['grade']));
+ //$output .= "assessing user $userid on assignment $assignmentid
";
+ //TODO find $submissionid from $userid & $assignmentid (may not exist yet, actually)
+ /*$submissionid = null;
+ $gradingwidget = $this->make_grading_widget($USER->id, $submissionid);
+ if ($gradingwidget instanceof renderable) {
+ return $output. $gradingrenderer->render($gradingwidget);
+ }*/
+ return $output;
+ }
+
// TODO the following functions may be moved to parent:
/**
@@ -273,4 +308,26 @@ class gradingform_rubric_controller extends gradingform_controller {
// TODO change filearea for embedded files in grading_definition.description
return $data;
}
+
+ public function is_form_available($foruserid = null) {
+ return true;
+ // TODO this is temporary for testing!
+ }
+
+ /**
+ *
+ */
+ public function default_validation_error_message() {
+ return 'Validation failed';
+ }
+
+ /**
+ *
+ */
+ public function validate_grading_element($elementvalue, $itemid) {
+ if ($elementvalue['grade'] > 100 || $elementvalue['grade'] < 0) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/grade/grading/lib.php b/grade/grading/lib.php
index 7a354d5b8e3..aed7f8530d7 100644
--- a/grade/grading/lib.php
+++ b/grade/grading/lib.php
@@ -374,6 +374,19 @@ class grading_manager {
return new $classname($this->context, $this->component, $this->area, $this->areacache->id);
}
+ /**
+ * Returns the controller for the active method if it is available
+ */
+ public function get_active_controller() {
+ if ($gradingmethod = $this->get_active_method()) {
+ $controller = $this->get_controller($gradingmethod);
+ if ($controller->is_form_available()) {
+ return $controller;
+ }
+ }
+ return null;
+ }
+
////////////////////////////////////////////////////////////////////////////
/**
diff --git a/lang/en/grading.php b/lang/en/grading.php
index 27ac999af00..5646d4773b3 100644
--- a/lang/en/grading.php
+++ b/lang/en/grading.php
@@ -26,6 +26,7 @@
defined('MOODLE_INTERNAL') || die();
+$string['exc_gradingformelement'] = 'Unable to instantiate grading form element';
$string['formnotavailable'] = 'Advanced grading method was selected to use but the grading form is not available yet. You may need to define it first via a link in the Settings block.';
$string['gradinginarea'] = 'Grading ({$a})';
$string['gradingmethod'] = 'Grading method';
diff --git a/lib/form/grading.php b/lib/form/grading.php
new file mode 100644
index 00000000000..ef11df553b1
--- /dev/null
+++ b/lib/form/grading.php
@@ -0,0 +1,118 @@
+.
+
+/**
+ * Element-container for advanced grading custom input
+ *
+ * @copyright 2011 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+global $CFG;
+require_once("HTML/QuickForm/element.php");
+require_once($CFG->dirroot.'/grade/grading/form/lib.php');
+
+if (class_exists('HTML_QuickForm')) {
+ HTML_QuickForm::registerRule('gradingvalidated', 'callback', '_validate', 'MoodleQuickForm_grading');
+}
+
+/**
+ * HTML class for a grading element
+ *
+ * @author Marina Glancy
+ * @access public
+ */
+class MoodleQuickForm_grading extends HTML_QuickForm_input{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+
+ private $gradingattributes;
+
+ function MoodleQuickForm_grading($elementName=null, $elementLabel=null, $attributes=null) {
+ parent::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
+ $this->gradingattributes = $attributes;
+ }
+
+ function toHtml(){
+ return $this->get_controller()->to_html($this);
+ }
+
+ function get_grading_attribute($name) {
+ return $this->gradingattributes[$name];
+ }
+
+ function get_controller() {
+ return $this->get_grading_attribute('controller');
+ }
+
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ * @param string $function function name to call to get html
+ */
+ function setHelpButton($helpbuttonargs, $function='helpbutton'){
+ debugging('component setHelpButton() is not used any more, please use $mform->setHelpButton() instead');
+ }
+
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+
+ /**
+ * @return string
+ */
+ function getElementTemplateType(){
+ return 'default';
+ }
+
+ /**
+ * Adds necessary rules to the element
+ */
+ function onQuickFormEvent($event, $arg, &$caller) {
+ if ($event == 'createElement') {
+ $attributes = $arg[2];
+ if (!is_array($attributes) || !array_key_exists('controller', $attributes) || !($attributes['controller'] instanceof gradingform_controller)) {
+ throw new moodle_exception('exc_gradingformelement', 'grading');
+ }
+ }
+
+ $name = $this->getName();
+ if ($name && $caller->elementExists($name)) {
+ $caller->addRule($name, $this->get_controller()->default_validation_error_message(), 'gradingvalidated', $this->gradingattributes);
+ }
+ return parent::onQuickFormEvent($event, $arg, $caller);
+ }
+
+ /**
+ * Function registered as rule for this element and is called when this element is being validated
+ */
+ static function _validate($elementValue, $attributes = null) {
+ return $attributes['controller']->validate_grading_element($elementValue, $attributes['submissionid']);
+ }
+}
diff --git a/lib/formslib.php b/lib/formslib.php
index 45e01a2092e..f02469e91b8 100644
--- a/lib/formslib.php
+++ b/lib/formslib.php
@@ -2487,6 +2487,7 @@ MoodleQuickForm::registerElementType('file', "$CFG->libdir/form/file.php", 'Mood
MoodleQuickForm::registerElementType('filemanager', "$CFG->libdir/form/filemanager.php", 'MoodleQuickForm_filemanager');
MoodleQuickForm::registerElementType('filepicker', "$CFG->libdir/form/filepicker.php", 'MoodleQuickForm_filepicker');
MoodleQuickForm::registerElementType('format', "$CFG->libdir/form/format.php", 'MoodleQuickForm_format');
+MoodleQuickForm::registerElementType('grading', "$CFG->libdir/form/grading.php", 'MoodleQuickForm_grading');
MoodleQuickForm::registerElementType('group', "$CFG->libdir/form/group.php", 'MoodleQuickForm_group');
MoodleQuickForm::registerElementType('header', "$CFG->libdir/form/header.php", 'MoodleQuickForm_header');
MoodleQuickForm::registerElementType('hidden', "$CFG->libdir/form/hidden.php", 'MoodleQuickForm_hidden');
diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php
index 59ac6175751..987f5b8eeb4 100644
--- a/mod/assignment/lib.php
+++ b/mod/assignment/lib.php
@@ -630,7 +630,10 @@ class assignment_base {
switch ($mode) {
case 'grade': // We are in a main window grading
- if ($submission = $this->process_feedback()) {
+ if (!$this->validate_and_preprocess_feedback()) {
+ // validation failed
+ $this->display_submission();
+ } else if ($submission = $this->process_feedback()) {
$this->display_submissions(get_string('changessaved'));
} else {
$this->display_submissions();
@@ -744,7 +747,11 @@ class assignment_base {
case 'saveandnext':
///We are in pop up. save the current one and go to the next one.
//first we save the current changes
- if ($submission = $this->process_feedback()) {
+ if (!$this->validate_and_preprocess_feedback()) {
+ // validation failed
+ $this->display_submission();
+ break;
+ } else if ($submission = $this->process_feedback()) {
//print_heading(get_string('changessaved'));
//$extra_javascript = $this->update_main_listing($submission);
}
@@ -1039,7 +1046,7 @@ class assignment_base {
} elseif ($assignment->assignmenttype == 'uploadsingle') {
$mformdata->fileui_options = array('subdirs'=>0, 'maxbytes'=>$CFG->userquota, 'maxfiles'=>1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
}
- $gradingman = get_grading_manager($this->context, 'mod_assignment', 'submission');
+ /*$gradingman = get_grading_manager($this->context, 'mod_assignment', 'submission');
if ($gradingmethod = $gradingman->get_active_method()) {
$controller = $gradingman->get_controller($gradingmethod);
if ($controller->is_form_available()) {
@@ -1067,6 +1074,13 @@ class assignment_base {
} else {
notice(get_string('formnotavailable', 'core_grading'), new moodle_url('/course/view.php', array('id' => $assignment->course)));
}
+ }*/
+ if ($controller = get_grading_manager($this->context, 'mod_assignment', 'submission')->get_active_controller()) {
+ if (!isset($submission->id)) {
+ // TODO this is a patch if submission id does not exist yet
+ $mformdata->submission = $this->get_submission($user->id, true);
+ }
+ $mformdata->advancedgradingcontroller = $controller;
}
$submitform = new mod_assignment_grading_form( null, $mformdata );
@@ -1074,7 +1088,9 @@ class assignment_base {
if (!$display) {
$ret_data = new stdClass();
$ret_data->mform = $submitform;
- $ret_data->fileui_options = $mformdata->fileui_options;
+ if (isset($mformdata->fileui_options)) {
+ $ret_data->fileui_options = $mformdata->fileui_options;
+ }
return $ret_data;
}
@@ -1574,6 +1590,33 @@ class assignment_base {
echo $OUTPUT->footer();
}
+ /**
+ * Validates the submitted form and returns false if validation did not pass.
+ * If validation passes, preprocess advanced grading (if applicable) and returns true.
+ */
+ function validate_and_preprocess_feedback() {
+ if (!$feedback = data_submitted()) {
+ return true; // No incoming data, nothing to validate
+ }
+ $userid = required_param('userid', PARAM_INT);
+ $offset = required_param('offset', PARAM_INT);
+ $submissiondata = $this->display_submission($offset, $userid, false);
+ $mform = $submissiondata->mform;
+ if ($mform->is_submitted()) {
+ if (!$mform->is_validated()) {
+ return false;
+ }
+ // preprocess advanced grading here
+ if ($controller = $mform->use_advanced_grading()) {
+ $data = $mform->get_data();
+ // TODO find better way to find submission id
+ $submission = $this->get_submission($userid);
+ $_POST['xgrade'] = $controller->save_and_get_grade($submission->id, $data->advancedgrading);
+ }
+ }
+ return true;
+ }
+
/**
* Process teacher feedback submission
*
@@ -2252,6 +2295,10 @@ class mod_assignment_grading_form extends moodleform {
global $OUTPUT;
$mform =& $this->_form;
+ if (isset($this->_customdata->advancedgradingcontroller)) {
+ $this->use_advanced_grading($this->_customdata->advancedgradingcontroller);
+ }
+
$formattr = $mform->getAttributes();
$formattr['id'] = 'submitform';
$mform->setAttributes($formattr);
@@ -2297,6 +2344,19 @@ class mod_assignment_grading_form extends moodleform {
}
+ private $_advancegradingcontroller;
+ /**
+ * Gets or sets the controller for advanced grading
+ *
+ * @param $controller
+ */
+ public function use_advanced_grading($controller = false) {
+ if ($controller !== false) {
+ $this->_advancegradingcontroller = $controller;
+ }
+ return $this->_advancegradingcontroller;
+ }
+
function add_grades_section() {
global $CFG;
$mform =& $this->_form;
@@ -2307,9 +2367,10 @@ class mod_assignment_grading_form extends moodleform {
$mform->addElement('header', 'Grades', get_string('grades', 'grades'));
- if (!empty($this->_customdata->advancedgradingenabled)) {
- $mform->addElement('static', 'advancedgradingwidget', get_string('grade').':', $this->_customdata->advancedgradingwidget);
-
+ if ($controller = $this->use_advanced_grading()) {
+ // TODO what if submission id does not exist yet!
+ $mform->addElement('grading', 'advancedgrading', get_string('grade').':',
+ array('controller' => $controller, 'submissionid' => $this->_customdata->submission->id));
} else {
// use simple direct grading
$grademenu = make_grades_menu($this->_customdata->assignment->grade);
@@ -2468,6 +2529,11 @@ class mod_assignment_grading_form extends moodleform {
}
$data = file_postupdate_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['component'], $editoroptions['filearea'], $itemid);
}
+
+ if ($this->use_advanced_grading() && !isset($data->advancedgrading)) {
+ $data->advancedgrading = null;
+ }
+
return $data;
}
}