mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-29483: advanced grading methods support on assignment module, grading form element, rubrics
- gradingform API now has not only controller class but also instance class with functions and data related to the particular grading instance - assignment grading form and grading form element deal with elements of gradingform_instance class instead of gradingform_controller - implemented the class gradingform_rubric_instance - added more phpdocs
This commit is contained in:
parent
671ec8f50e
commit
36937f0264
@ -287,65 +287,92 @@ abstract class gradingform_controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure there is a form instance for the given rater grading the given item
|
||||
* Returns the ACTIVE instance for this definition for the specified $raterid and $itemid
|
||||
* (if multiple raters are allowed, or only for $itemid otherwise).
|
||||
*
|
||||
* Plugins will probably override/extend this and load additional data of how their
|
||||
* forms are filled in one complex query.
|
||||
*
|
||||
* @todo this might actually become abstract method
|
||||
* @param int $raterid
|
||||
* @param int $itemid
|
||||
* @return stdClass newly created or existing record from {grading_instances}
|
||||
* @param boolean $idonly
|
||||
* @return mixed if $idonly=true returns id of the found instance, otherwise returns the instance object
|
||||
*/
|
||||
public function prepare_instance($raterid, $itemid) {
|
||||
public function get_current_instance($raterid, $itemid, $idonly = false) {
|
||||
global $DB;
|
||||
|
||||
if (empty($this->definition)) {
|
||||
throw new coding_exception('Attempting to prepare an instance of non-existing grading form');
|
||||
$select = array(
|
||||
'formid' => $this->definition->id,
|
||||
'itemid' => $itemid,
|
||||
'status' => gradingform_instance::INSTANCE_STATUS_ACTIVE);
|
||||
if (false /* TODO $manager->allow_multiple_raters() */) {
|
||||
$select['raterid'] = $raterid;
|
||||
}
|
||||
|
||||
$current = $DB->get_record('grading_instances', array(
|
||||
'formid' => $this->definition->id,
|
||||
'raterid' => $raterid,
|
||||
'itemid' => $itemid), '*', IGNORE_MISSING);
|
||||
|
||||
if (empty($current)) {
|
||||
$instance = new stdClass();
|
||||
$instance->formid = $this->definition->id;
|
||||
$instance->raterid = $raterid;
|
||||
$instance->itemid = $itemid;
|
||||
$instance->timemodified = time();
|
||||
$instance->feedbackformat = FORMAT_MOODLE;
|
||||
$instance->id = $DB->insert_record('grading_instances', $instance);
|
||||
return $instance;
|
||||
|
||||
if ($idonly) {
|
||||
if ($current = $DB->get_record('grading_instances', $select, 'id', IGNORE_MISSING)) {
|
||||
return $current->id;
|
||||
}
|
||||
} else {
|
||||
return $current;
|
||||
if ($current = $DB->get_record('grading_instances', $select, '*', IGNORE_MISSING)) {
|
||||
return $this->get_instance($current);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves non-js data and returns the gradebook grade
|
||||
*/
|
||||
abstract public function save_and_get_grade($raterid, $itemid, $formdata);
|
||||
|
||||
/**
|
||||
* Returns html for form element
|
||||
*/
|
||||
abstract public function to_html($gradingformelement);
|
||||
|
||||
/**
|
||||
* Returns list of active instances for the specified $itemid
|
||||
*
|
||||
* @param int $itemid
|
||||
* @return array of gradingform_instance objects
|
||||
*/
|
||||
public function default_validation_error_message() {
|
||||
return '';
|
||||
public function get_current_instances($itemid) {
|
||||
global $DB;
|
||||
$conditions = array('formid' => $this->definition->id,
|
||||
'itemid' => $itemid,
|
||||
'status' => gradingform_instance::INSTANCE_STATUS_ACTIVE);
|
||||
$records = $DB->get_recordset('grading_instances', $conditions);
|
||||
$rv = array();
|
||||
foreach ($records as $record) {
|
||||
$rv[] = $this->get_instance($record);
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object of type gradingform_XXX_instance (where XXX is the plugin method name)
|
||||
*
|
||||
* @param mixed $instance id or row from grading_isntances table
|
||||
* @return gradingform_instance
|
||||
*/
|
||||
public function validate_grading_element($elementvalue, $itemid) {
|
||||
return true;
|
||||
protected function get_instance($instance) {
|
||||
global $DB;
|
||||
if (is_scalar($instance)) {
|
||||
// instance id is passed as parameter
|
||||
$instance = $DB->get_record('grading_instances', array('id' => $instance), '*', MUST_EXIST);
|
||||
}
|
||||
if ($instance) {
|
||||
$class = 'gradingform_'. $this->get_method_name(). '_instance';
|
||||
return new $class($this, $instance);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is invoked when user (teacher) starts grading.
|
||||
* It creates and returns copy of the current ACTIVE instance if it exists. If this is the
|
||||
* first grading attempt, a new instance is created.
|
||||
* The status of the returned instance is INCOMPLETE
|
||||
*
|
||||
* @param int $raterid
|
||||
* @param int $itemid
|
||||
* @return gradingform_instance
|
||||
*/
|
||||
public function create_instance($raterid, $itemid) {
|
||||
global $DB;
|
||||
// first find if there is already an active instance for this itemid
|
||||
if ($current = $this->get_current_instance($raterid, $itemid)) {
|
||||
return $this->get_instance($current->copy($raterid, $itemid));
|
||||
} else {
|
||||
$class = 'gradingform_'. $this->get_method_name(). '_instance';
|
||||
return $this->get_instance($class::create_new($this->definition->id, $raterid, $itemid));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -426,4 +453,225 @@ abstract class gradingform_controller {
|
||||
throw new coding_exception('Invalid class name');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns html code to be included in student's feedback.
|
||||
*
|
||||
* @param moodle_page $page
|
||||
* @param int $itemid
|
||||
* @param string $defaultcontent default string to be returned if no active grading is found
|
||||
* @return string
|
||||
*/
|
||||
public function render_grade($page, $itemid, $defaultcontent) {
|
||||
return $defaultcontent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to manage one grading instance. Stores information and performs actions like
|
||||
* update, copy, validate, submit, etc.
|
||||
*
|
||||
* @copyright 2011 Marina Glancy
|
||||
*/
|
||||
abstract class gradingform_instance {
|
||||
const INSTANCE_STATUS_ACTIVE = 1;
|
||||
const INSTANCE_STATUS_INCOMPLETE = 0;
|
||||
const INSTANCE_STATUS_ARCHIVE = 3;
|
||||
|
||||
/** @var stdClass record from table grading_instances */
|
||||
protected $data;
|
||||
/** @var gradingform_controller link to the corresponding controller */
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* Creates an instance
|
||||
*
|
||||
* @param gradingform_controller $controller
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function __construct($controller, $data) {
|
||||
$this->data = (object)$data;
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty instance in DB and mark its status as INCOMPLETE
|
||||
*
|
||||
* @param int $formid
|
||||
* @param int $raterid
|
||||
* @param int $itemid
|
||||
* @return int id of the created instance
|
||||
*/
|
||||
public static function create_new($formid, $raterid, $itemid) {
|
||||
global $DB;
|
||||
$instance = new stdClass();
|
||||
$instance->formid = $formid;
|
||||
$instance->raterid = $raterid;
|
||||
$instance->itemid = $itemid;
|
||||
$instance->status = self::INSTANCE_STATUS_INCOMPLETE;
|
||||
$instance->timemodified = time();
|
||||
$instance->feedbackformat = FORMAT_MOODLE;
|
||||
$instanceid = $DB->insert_record('grading_instances', $instance);
|
||||
return $instanceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates the instance before editing (optionally substitutes raterid and/or itemid with
|
||||
* the specified values)
|
||||
* Plugins may want to override this function to copy data from additional tables as well
|
||||
*
|
||||
* @param int $raterid value for raterid in the duplicate
|
||||
* @param int $itemid value for itemid in the duplicate
|
||||
* @return int id of the new instance
|
||||
*/
|
||||
public function copy($raterid, $itemid) {
|
||||
global $DB;
|
||||
$data = (array)$this->data; // Cast to array to make a copy
|
||||
unset($data['id']);
|
||||
$data['raterid'] = $raterid;
|
||||
$data['itemid'] = $itemid;
|
||||
$data['timemodified'] = time();
|
||||
$data['status'] = self::INSTANCE_STATUS_INCOMPLETE;
|
||||
$instanceid = $DB->insert_record('grading_instances', $data);
|
||||
return $instanceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the controller
|
||||
*
|
||||
* @return gradingform_controller
|
||||
*/
|
||||
public function get_controller() {
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instance id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->data->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the instance as ACTIVE and current active instance (if exists) as ARCHIVE
|
||||
*/
|
||||
protected function make_active() {
|
||||
global $DB;
|
||||
if ($this->data->status == self::INSTANCE_STATUS_ACTIVE) {
|
||||
// already active
|
||||
return;
|
||||
}
|
||||
$currentid = $this->get_controller()->get_current_instance($this->data->raterid, $this->data->itemid, true);
|
||||
if ($currentid) {
|
||||
if ($currentid != $this->get_id()) {
|
||||
$DB->update_record('grading_instances', array('id' => $currentid, 'status' => self::INSTANCE_STATUS_ARCHIVE));
|
||||
$DB->update_record('grading_instances', array('id' => $this->get_id(), 'status' => self::INSTANCE_STATUS_ACTIVE));
|
||||
}
|
||||
} else {
|
||||
$DB->update_record('grading_instances', array('id' => $this->get_id(), 'status' => self::INSTANCE_STATUS_ACTIVE));
|
||||
}
|
||||
$this->data->status = self::INSTANCE_STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this (INCOMPLETE) instance from database. This function is invoked on cancelling the
|
||||
* grading form and/or during cron cleanup.
|
||||
* Plugins using additional tables must override this method to remove additional data.
|
||||
* Note that if the teacher just closes the window or presses 'Back' button of the browser,
|
||||
* this function is not invoked.
|
||||
*/
|
||||
public function cancel() {
|
||||
global $DB;
|
||||
// TODO what if we happen delete the ACTIVE instance, shall we rollback to the last ARCHIVE? or throw an exception?
|
||||
// TODO create cleanup cron
|
||||
$DB->delete_records('grading_instances', array('id' => $this->get_id()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the instance with the data received from grading form. This function may be
|
||||
* called via AJAX when grading is not yet completed, so it does not change the
|
||||
* status of the instance.
|
||||
*/
|
||||
public function update($elementvalue) {
|
||||
// TODO update timemodified at least
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the grade to be pushed to the gradebook
|
||||
* @return int the grade on 0-100 scale
|
||||
*/
|
||||
abstract public function get_grade();
|
||||
|
||||
/**
|
||||
* Called when teacher submits the grading form:
|
||||
* updates the instance in DB, marks it as ACTIVE and returns the grade to be pushed to the gradebook
|
||||
* @return int the grade on 0-100 scale
|
||||
*/
|
||||
public function submit_and_get_grade($elementvalue) {
|
||||
$this->update($elementvalue);
|
||||
$this->make_active();
|
||||
return $this->get_grade();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns html for form element of type 'grading'. If there is a form input element
|
||||
* it must have the name $gradingformelement->getName().
|
||||
* If there are more than one input elements they MUST be elements of array with
|
||||
* name $gradingformelement->getName().
|
||||
* Example: {NAME}[myelement1], {NAME}[myelement2][sub1], {NAME}[myelement2][sub2], etc.
|
||||
* After submitting the form the value of $_POST[{NAME}] is passed to the functions
|
||||
* validate_grading_element() and submit_and_get_grade()
|
||||
*
|
||||
* Plugins may use $gradingformelement->getValue() to get the value passed on previous
|
||||
* from submit
|
||||
*
|
||||
* When forming html it is a plugin's responsibility to analyze flags
|
||||
* $gradingformelement->_flagFrozen and $gradingformelement->_persistantFreeze:
|
||||
*
|
||||
* (_flagFrozen == false) => form element is editable
|
||||
*
|
||||
* (_flagFrozen == false && _persistantFreeze == true) => form element is not editable
|
||||
* but all values are passed as hidden elements
|
||||
*
|
||||
* (_flagFrozen == false && _persistantFreeze == false) => form element is not editable
|
||||
* and no values are passed as hidden elements
|
||||
*
|
||||
* Plugins are welcome to use AJAX in the form element. But it is strongly recommended
|
||||
* that the grading only becomes active when teacher presses 'Submit' button (the
|
||||
* method submit_and_get_grade() is invoked)
|
||||
*
|
||||
* Also client-side JS validation may be implemented here
|
||||
*
|
||||
* @see MoodleQuickForm_grading in lib/form/grading.php
|
||||
*
|
||||
* @param moodle_page $page
|
||||
* @param MoodleQuickForm_grading $gradingformelement
|
||||
* @return string
|
||||
*/
|
||||
abstract function render_grading_element($page, $gradingformelement);
|
||||
|
||||
/**
|
||||
* Server-side validation of the data received from grading form.
|
||||
*
|
||||
* @param mixed $elementvalue is the scalar or array received in $_POST
|
||||
* @return boolean true if the form data is validated and contains no errors
|
||||
*/
|
||||
public function validate_grading_element($elementvalue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message displayed if validation failed.
|
||||
* If plugin wants to display custom message, the empty string should be returned here
|
||||
* and the custom message should be output in render_grading_element()
|
||||
*
|
||||
* @see validate_grading_element()
|
||||
* @return string
|
||||
*/
|
||||
public function default_validation_error_message() {
|
||||
return '';
|
||||
}
|
||||
}
|
@ -266,182 +266,6 @@ class gradingform_rubric_controller extends gradingform_controller {
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function get_grading($raterid, $itemid) {
|
||||
global $DB;
|
||||
$sql = "SELECT f.id, f.criterionid, f.levelid, f.remark, f.remarkformat
|
||||
FROM {grading_instances} i, {gradingform_rubric_fillings} f
|
||||
WHERE i.formid = :formid ".
|
||||
"AND i.raterid = :raterid ".
|
||||
"AND i.itemid = :itemid
|
||||
AND i.id = f.forminstanceid";
|
||||
$params = array('formid' => $this->definition->id, 'itemid' => $itemid, 'raterid' => $raterid);
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
$grading = array();
|
||||
foreach ($rs as $record) {
|
||||
if ($record->levelid) {
|
||||
$grading[$record->criterionid] = $record->levelid;
|
||||
}
|
||||
// TODO: remarks
|
||||
}
|
||||
$rs->close();
|
||||
return $grading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the rubric data to the gradebook score 0-100
|
||||
*/
|
||||
protected function calculate_grade($grade, $itemid) {
|
||||
if (!$this->validate_grading_element($grade, $itemid)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$minscore = 0;
|
||||
$maxscore = 0;
|
||||
foreach ($this->definition->rubric_criteria as $id => $criterion) {
|
||||
$keys = array_keys($criterion['levels']);
|
||||
// TODO array_reverse($keys) if levels are sorted DESC
|
||||
$minscore += $criterion['levels'][$keys[0]]['score'];
|
||||
$maxscore += $criterion['levels'][$keys[sizeof($keys)-1]]['score'];
|
||||
}
|
||||
|
||||
if ($maxscore == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$curscore = 0;
|
||||
foreach ($grade as $id => $levelid) {
|
||||
$curscore += $this->definition->rubric_criteria[$id]['levels'][$levelid]['score'];
|
||||
}
|
||||
return $curscore/$maxscore*100; // TODO mapping
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves non-js data and returns the gradebook grade
|
||||
*/
|
||||
public function save_and_get_grade($raterid, $itemid, $formdata) {
|
||||
global $DB, $USER;
|
||||
$instance = $this->prepare_instance($raterid, $itemid);
|
||||
$currentgrade = $this->get_grading($raterid, $itemid);
|
||||
if (!is_array($formdata)) {
|
||||
return $this->calculate_grade($currentgrade, $itemid);
|
||||
}
|
||||
foreach ($formdata as $criterionid => $levelid) {
|
||||
$params = array('forminstanceid' => $instance->id, 'criterionid' => $criterionid);
|
||||
if (!array_key_exists($criterionid, $currentgrade)) {
|
||||
$DB->insert_record('gradingform_rubric_fillings', $params + array('levelid' => $levelid));
|
||||
} else if ($currentgrade[$criterionid] != $levelid) {
|
||||
$DB->set_field('gradingform_rubric_fillings', 'levelid', $levelid, $params);
|
||||
}
|
||||
}
|
||||
foreach ($currentgrade as $criterionid => $levelid) {
|
||||
if (!array_key_exists($criterionid, $formdata)) {
|
||||
$params = array('forminstanceid' => $instance->id, 'criterionid' => $criterionid);
|
||||
$DB->delete_records('gradingform_rubric_fillings', $params);
|
||||
}
|
||||
}
|
||||
// TODO: remarks
|
||||
return $this->calculate_grade($formdata, $itemid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns html for form element
|
||||
*/
|
||||
public function to_html($gradingformelement) {
|
||||
global $PAGE, $USER;
|
||||
if (!$gradingformelement->_flagFrozen) {
|
||||
$module = array('name'=>'gradingform_rubric', 'fullpath'=>'/grade/grading/form/rubric/js/rubric.js');
|
||||
$PAGE->requires->js_init_call('M.gradingform_rubric.init', array(array('name' => $gradingformelement->getName(), 'criteriontemplate' =>'', 'leveltemplate' => '')), true, $module);
|
||||
$mode = self::DISPLAY_EVAL;
|
||||
} else {
|
||||
if ($this->_persistantFreeze) {
|
||||
$mode = gradingform_rubric_controller::DISPLAY_EVAL_FROZEN;
|
||||
} else {
|
||||
$mode = gradingform_rubric_controller::DISPLAY_REVIEW;
|
||||
}
|
||||
}
|
||||
$criteria = $this->definition->rubric_criteria;
|
||||
$submissionid = $gradingformelement->get_grading_attribute('submissionid');
|
||||
$raterid = $USER->id; // TODO - this is very strange!
|
||||
$value = $gradingformelement->getValue();
|
||||
if ($value === null) {
|
||||
$value = $this->get_grading($raterid, $submissionid); // TODO maybe implement in form->set_data() ?
|
||||
}
|
||||
return $this->get_renderer($PAGE)->display_rubric($criteria, $mode, $gradingformelement->getName(), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns html for form element
|
||||
*/
|
||||
public function to_html_old($gradingformelement) {
|
||||
global $PAGE, $USER;
|
||||
//TODO move to renderer
|
||||
|
||||
//$gradingrenderer = $this->prepare_renderer($PAGE);
|
||||
$html = '';
|
||||
$elementname = $gradingformelement->getName();
|
||||
$elementvalue = $gradingformelement->getValue();
|
||||
$submissionid = $gradingformelement->get_grading_attribute('submissionid');
|
||||
$raterid = $USER->id; // TODO - this is very strange!
|
||||
$html .= "assessing submission $submissionid<br />";
|
||||
//$html .= html_writer::empty_tag('input', array('type' => 'text', 'name' => $elementname.'[grade]', 'size' => '20', 'value' => $elementvalue['grade']));
|
||||
|
||||
if (!$gradingformelement->_flagFrozen) {
|
||||
$module = array('name'=>'gradingform_rubric', 'fullpath'=>'/grade/grading/form/rubric/js/rubric.js');
|
||||
$PAGE->requires->js_init_call('M.gradingform_rubric.init', array(array('name' => $gradingformelement->getName(), 'criteriontemplate' =>'', 'leveltemplate' => '')), true, $module);
|
||||
}
|
||||
$criteria = $this->definition->rubric_criteria;
|
||||
|
||||
$html .= html_writer::start_tag('div', array('id' => 'rubric-'.$gradingformelement->getName(), 'class' => 'form_rubric evaluate'));
|
||||
$criteria_cnt = 0;
|
||||
|
||||
$value = $gradingformelement->getValue();
|
||||
if ($value === null) {
|
||||
$value = $this->get_grading($raterid, $submissionid); // TODO maybe implement in form->set_data() ?
|
||||
}
|
||||
|
||||
foreach ($criteria as $criterionid => $criterion) {
|
||||
$html .= html_writer::start_tag('div', array('class' => 'criterion'.$this->get_css_class_suffix($criteria_cnt++, count($criteria)-1)));
|
||||
$html .= html_writer::tag('div', $criterion['description'], array('class' => 'description')); // TODO descriptionformat
|
||||
$html .= html_writer::start_tag('div', array('class' => 'levels'));
|
||||
$level_cnt = 0;
|
||||
foreach ($criterion['levels'] as $levelid => $level) {
|
||||
$checked = (is_array($value) && array_key_exists($criterionid, $value) && ((int)$value[$criterionid] === $levelid));
|
||||
$classsuffix = $this->get_css_class_suffix($level_cnt++, count($criterion['levels'])-1);
|
||||
if ($checked) {
|
||||
$classsuffix .= ' checked';
|
||||
}
|
||||
$html .= html_writer::start_tag('div', array('id' => $gradingformelement->getName().'-'.$criterionid.'-levels-'.$levelid, 'class' => 'level'.$classsuffix));
|
||||
$input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => $gradingformelement->getName().'['.$criterionid.']', 'value' => $levelid) +
|
||||
($checked ? array('checked' => 'checked') : array())); // TODO rewrite
|
||||
$html .= html_writer::tag('div', $input, array('class' => 'radio'));
|
||||
$html .= html_writer::tag('div', $level['definition'], array('class' => 'definition')); // TODO definitionformat
|
||||
$html .= html_writer::tag('div', (float)$level['score'].' pts', array('class' => 'score')); //TODO span, get_string
|
||||
$html .= html_writer::end_tag('div'); // .level
|
||||
}
|
||||
$html .= html_writer::end_tag('div'); // .levels
|
||||
$html .= html_writer::end_tag('div'); // .criterion
|
||||
}
|
||||
$html .= html_writer::end_tag('div'); // .rubric
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
private function get_css_class_suffix($cnt, $maxcnt) {
|
||||
$class = '';
|
||||
if ($cnt == 0) {
|
||||
$class .= ' first';
|
||||
}
|
||||
if ($cnt == $maxcnt) {
|
||||
$class .= ' last';
|
||||
}
|
||||
if ($cnt%2) {
|
||||
$class .= ' odd';
|
||||
} else {
|
||||
$class .= ' even';
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
// TODO the following functions may be moved to parent:
|
||||
|
||||
/**
|
||||
@ -495,32 +319,6 @@ class gradingform_rubric_controller extends gradingform_controller {
|
||||
// TODO this is temporary for testing!
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message displayed in case of validation failed
|
||||
*
|
||||
* @see validate_grading_element
|
||||
*/
|
||||
public function default_validation_error_message() {
|
||||
return 'The rubric is incomplete'; //TODO string
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that rubric is fully completed and contains valid grade on each criterion
|
||||
*/
|
||||
public function validate_grading_element($elementvalue, $itemid) {
|
||||
// TODO: if there is nothing selected in rubric, we don't enter this function at all :(
|
||||
$criteria = $this->definition->rubric_criteria;
|
||||
if (!is_array($elementvalue) || sizeof($elementvalue) < sizeof($criteria)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($criteria as $id => $criterion) {
|
||||
if (!array_key_exists($id, $elementvalue) || !array_key_exists($elementvalue[$id], $criterion['levels'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rubric plugin renderer
|
||||
*
|
||||
@ -544,8 +342,8 @@ class gradingform_rubric_controller extends gradingform_controller {
|
||||
|
||||
// append the rubric itself, using own renderer
|
||||
$output = $this->get_renderer($page);
|
||||
// todo something like $rubric = $output->render_preview($this);
|
||||
$rubric = '[[TODO RUBRIC PREVIEW]]';
|
||||
$criteria = $this->definition->rubric_criteria;
|
||||
$rubric = $output->display_rubric($criteria, self::DISPLAY_PREVIEW, 'rubric');
|
||||
|
||||
return $header . $rubric;
|
||||
}
|
||||
@ -569,4 +367,183 @@ class gradingform_rubric_controller extends gradingform_controller {
|
||||
// delete critera
|
||||
$DB->delete_records_list('gradingform_rubric_criteria', 'id', $criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns html code to be included in student's feedback.
|
||||
*
|
||||
* @param moodle_page $page
|
||||
* @param int $itemid
|
||||
* @param string $defaultcontent default string to be returned if no active grading is found
|
||||
* @return string
|
||||
*/
|
||||
public function render_grade($page, $itemid, $defaultcontent) {
|
||||
$instances = $this->get_current_instances($itemid);
|
||||
return $this->get_renderer($page)->display_instances($this->get_current_instances($itemid), $defaultcontent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to manage one rubric grading instance. Stores information and performs actions like
|
||||
* update, copy, validate, submit, etc.
|
||||
*
|
||||
* @copyright 2011 Marina Glancy
|
||||
*/
|
||||
class gradingform_rubric_instance extends gradingform_instance {
|
||||
|
||||
/**
|
||||
* Deletes this (INCOMPLETE) instance from database.
|
||||
*/
|
||||
public function cancel() {
|
||||
global $DB;
|
||||
parent::cancel();
|
||||
$DB->delete_records('gradingform_rubric_fillings', array('forminstanceid' => $this->get_id()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates the instance before editing (optionally substitutes raterid and/or itemid with
|
||||
* the specified values)
|
||||
*
|
||||
* @param int $raterid value for raterid in the duplicate
|
||||
* @param int $itemid value for itemid in the duplicate
|
||||
* @return int id of the new instance
|
||||
*/
|
||||
public function copy($raterid, $itemid) {
|
||||
global $DB;
|
||||
$instanceid = parent::copy($raterid, $itemid);
|
||||
$currentgrade = $this->get_rubric_filling();
|
||||
foreach ($currentgrade as $criterionid => $levelid) {
|
||||
$params = array('forminstanceid' => $instanceid, 'criterionid' => $criterionid, 'levelid' => $levelid);
|
||||
$DB->insert_record('gradingform_rubric_fillings', $params);
|
||||
}
|
||||
// TODO remarks
|
||||
return $instanceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that rubric is fully completed and contains valid grade on each criterion
|
||||
* @return boolean true if the form data is validated and contains no errors
|
||||
*/
|
||||
public function validate_grading_element($elementvalue) {
|
||||
// TODO: if there is nothing selected in rubric, we don't enter this function at all :(
|
||||
$criteria = $this->get_controller()->get_definition()->rubric_criteria;
|
||||
if (!is_array($elementvalue) || sizeof($elementvalue) < sizeof($criteria)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($criteria as $id => $criterion) {
|
||||
if (!array_key_exists($id, $elementvalue) || !array_key_exists($elementvalue[$id], $criterion['levels'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves from DB and returns the data how this rubric was filled
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_rubric_filling() {
|
||||
// TODO cache
|
||||
global $DB;
|
||||
$rs = $DB->get_records('gradingform_rubric_fillings', array('forminstanceid' => $this->get_id()));
|
||||
$grading = array();
|
||||
foreach ($rs as $record) {
|
||||
if ($record->levelid) {
|
||||
$grading[$record->criterionid] = $record->levelid;
|
||||
}
|
||||
// TODO: remarks
|
||||
}
|
||||
return $grading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the instance with the data received from grading form. This function may be
|
||||
* called via AJAX when grading is not yet completed, so it does not change the
|
||||
* status of the instance.
|
||||
*/
|
||||
public function update($data) {
|
||||
global $DB;
|
||||
$currentgrade = $this->get_rubric_filling();
|
||||
parent::update($data); // TODO ? +timemodified
|
||||
foreach ($data as $criterionid => $levelid) {
|
||||
$params = array('forminstanceid' => $this->get_id(), 'criterionid' => $criterionid);
|
||||
if (!array_key_exists($criterionid, $currentgrade)) {
|
||||
$DB->insert_record('gradingform_rubric_fillings', $params + array('levelid' => $levelid));
|
||||
} else if ($currentgrade[$criterionid] != $levelid) {
|
||||
$DB->set_field('gradingform_rubric_fillings', 'levelid', $levelid, $params);
|
||||
}
|
||||
}
|
||||
foreach ($currentgrade as $criterionid => $levelid) {
|
||||
if (!array_key_exists($criterionid, $data)) {
|
||||
$params = array('forminstanceid' => $this->get_id(), 'criterionid' => $criterionid);
|
||||
$DB->delete_records('gradingform_rubric_fillings', $params);
|
||||
}
|
||||
}
|
||||
// TODO: remarks
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the grade to be pushed to the gradebook
|
||||
* @return int the grade on 0-100 scale
|
||||
*/
|
||||
public function get_grade() {
|
||||
global $DB, $USER;
|
||||
$grade = $this->get_rubric_filling();
|
||||
|
||||
$minscore = 0;
|
||||
$maxscore = 0;
|
||||
foreach ($this->get_controller()->get_definition()->rubric_criteria as $id => $criterion) {
|
||||
$keys = array_keys($criterion['levels']);
|
||||
// TODO array_reverse($keys) if levels are sorted DESC
|
||||
$minscore += $criterion['levels'][$keys[0]]['score'];
|
||||
$maxscore += $criterion['levels'][$keys[sizeof($keys)-1]]['score'];
|
||||
}
|
||||
|
||||
if ($maxscore == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$curscore = 0;
|
||||
foreach ($grade as $id => $levelid) {
|
||||
$curscore += $this->get_controller()->get_definition()->rubric_criteria[$id]['levels'][$levelid]['score'];
|
||||
}
|
||||
return $curscore/$maxscore*100; // TODO mapping
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message displayed in case of validation failed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function default_validation_error_message() {
|
||||
return 'The rubric is incomplete'; //TODO string
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns html for form element of type 'grading'.
|
||||
*
|
||||
* @param moodle_page $page
|
||||
* @param MoodleQuickForm_grading $formelement
|
||||
* @return string
|
||||
*/
|
||||
public function render_grading_element($page, $gradingformelement) {
|
||||
global $USER;
|
||||
if (!$gradingformelement->_flagFrozen) {
|
||||
$module = array('name'=>'gradingform_rubric', 'fullpath'=>'/grade/grading/form/rubric/js/rubric.js');
|
||||
$page->requires->js_init_call('M.gradingform_rubric.init', array(array('name' => $gradingformelement->getName())), true, $module);
|
||||
$mode = gradingform_rubric_controller::DISPLAY_EVAL;
|
||||
} else {
|
||||
if ($gradingformelement->_persistantFreeze) {
|
||||
$mode = gradingform_rubric_controller::DISPLAY_EVAL_FROZEN;
|
||||
} else {
|
||||
$mode = gradingform_rubric_controller::DISPLAY_REVIEW;
|
||||
}
|
||||
}
|
||||
$criteria = $this->get_controller()->get_definition()->rubric_criteria;
|
||||
$value = $gradingformelement->getValue();
|
||||
if ($value === null) {
|
||||
$value = $this->get_rubric_filling();
|
||||
}
|
||||
return $this->get_controller()->get_renderer($page)->display_rubric($criteria, $mode, $gradingformelement->getName(), $value);
|
||||
}
|
||||
}
|
@ -213,4 +213,35 @@ class gradingform_rubric_renderer {
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays for the student the list of instances or default content if no instances found
|
||||
*
|
||||
* @param array $instances array of objects of type gradingform_rubric_instance
|
||||
* @param string $defaultcontent default string that would be displayed without advanced grading
|
||||
* @return string
|
||||
*/
|
||||
public function display_instances($instances, $defaultcontent) {
|
||||
if (sizeof($instances)) {
|
||||
$rv = html_writer::start_tag('div', array('class' => 'advancedgrade'));
|
||||
$idx = 0;
|
||||
foreach ($instances as $instance) {
|
||||
$rv .= $this->display_instance($instance, $idx++);
|
||||
}
|
||||
$rv .= html_writer::end_tag('div');
|
||||
}
|
||||
return $rv. $defaultcontent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays one grading instance
|
||||
*
|
||||
* @param gradingform_rubric_instance $instance
|
||||
* @param int idx unique number of instance on page
|
||||
*/
|
||||
public function display_instance(gradingform_rubric_instance $instance, $idx) {
|
||||
$criteria = $instance->get_controller()->get_definition()->rubric_criteria;
|
||||
$values = $instance->get_rubric_filling();
|
||||
return $this->display_rubric($criteria, gradingform_rubric_controller::DISPLAY_REVIEW, 'rubric'.$idx, $values);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@
|
||||
.form_rubric.editor .criterion.last .controls .movedown input {display:none;}
|
||||
|
||||
/* evaluation */
|
||||
.form_rubric.evaluate .criterion .levels .level.checked {background:#d0ffd0;}
|
||||
.form_rubric .criterion .levels .level.checked {background:#d0ffd0;}
|
||||
.form_rubric.evaluate .criterion .levels .level:hover {background:#30ff30;}
|
||||
|
||||
/* replace buttons with images */
|
||||
|
@ -31,7 +31,11 @@ if (class_exists('HTML_QuickForm')) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML class for a grading element
|
||||
* HTML class for a grading element. This is a wrapper for advanced grading plugins.
|
||||
* When adding the 'grading' element to the form, developer must pass an object of
|
||||
* class gradingform_instance as $attributes['gradinginstance']. Otherwise an exception will be
|
||||
* thrown.
|
||||
* This object is responsible for implementing functions to render element html and validate it
|
||||
*
|
||||
* @author Marina Glancy
|
||||
* @access public
|
||||
@ -44,6 +48,10 @@ class MoodleQuickForm_grading extends HTML_QuickForm_input{
|
||||
*/
|
||||
var $_helpbutton='';
|
||||
|
||||
/**
|
||||
* Stores attributes passed to the element
|
||||
* @var array
|
||||
*/
|
||||
private $gradingattributes;
|
||||
|
||||
function MoodleQuickForm_grading($elementName=null, $elementLabel=null, $attributes=null) {
|
||||
@ -51,16 +59,27 @@ class MoodleQuickForm_grading extends HTML_QuickForm_input{
|
||||
$this->gradingattributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to retrieve gradingform_instance passed in element attributes
|
||||
*
|
||||
* @return gradingform_instance
|
||||
*/
|
||||
function get_gradinginstance() {
|
||||
if (is_array($this->gradingattributes) && array_key_exists('gradinginstance', $this->gradingattributes)) {
|
||||
return $this->gradingattributes['gradinginstance'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input field in HTML
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
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');
|
||||
global $PAGE;
|
||||
return $this->get_gradinginstance()->render_grading_element($PAGE, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,22 +116,23 @@ class MoodleQuickForm_grading extends HTML_QuickForm_input{
|
||||
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)) {
|
||||
if (!is_array($attributes) || !array_key_exists('gradinginstance', $attributes) || !($attributes['gradinginstance'] instanceof gradingform_instance)) {
|
||||
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);
|
||||
$caller->addRule($name, $this->get_gradinginstance()->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
|
||||
* Function registered as rule for this element and is called when this element is being validated.
|
||||
* This is a wrapper to pass the validation to the method gradingform_instance::validate_grading_element
|
||||
*/
|
||||
static function _validate($elementValue, $attributes = null) {
|
||||
return $attributes['controller']->validate_grading_element($elementValue, $attributes['submissionid']);
|
||||
return $attributes['gradinginstance']->validate_grading_element($elementValue);
|
||||
}
|
||||
}
|
||||
|
@ -264,8 +264,9 @@ class assignment_base {
|
||||
* @param object $submission The submission object or NULL in which case it will be loaded
|
||||
*/
|
||||
function view_feedback($submission=NULL) {
|
||||
global $USER, $CFG, $DB, $OUTPUT;
|
||||
global $USER, $CFG, $DB, $OUTPUT, $PAGE;
|
||||
require_once($CFG->libdir.'/gradelib.php');
|
||||
require_once("$CFG->dirroot/grade/grading/lib.php");
|
||||
|
||||
if (!is_enrolled($this->context, $USER, 'mod/assignment:view')) {
|
||||
// can not submit assignments -> no feedback
|
||||
@ -329,9 +330,12 @@ class assignment_base {
|
||||
echo '<tr>';
|
||||
echo '<td class="left side"> </td>';
|
||||
echo '<td class="content">';
|
||||
echo '<div class="grade">';
|
||||
echo get_string("grade").': '.$grade->str_long_grade;
|
||||
echo '</div>';
|
||||
$grade_str = '<div class="grade">'. get_string("grade").': '.$grade->str_long_grade. '</div>';
|
||||
if (!empty($submission) && $controller = get_grading_manager($this->context, 'mod_assignment', 'submission')->get_active_controller()) {
|
||||
echo $controller->render_grade($PAGE, $submission->id, $grade_str);
|
||||
} else {
|
||||
echo $grade_str;
|
||||
}
|
||||
echo '<div class="clearer"></div>';
|
||||
|
||||
echo '<div class="comment">';
|
||||
@ -608,7 +612,6 @@ class assignment_base {
|
||||
|
||||
//make user global so we can use the id
|
||||
global $USER, $OUTPUT, $DB, $PAGE;
|
||||
|
||||
$mailinfo = optional_param('mailinfo', null, PARAM_BOOL);
|
||||
|
||||
if (optional_param('next', null, PARAM_BOOL)) {
|
||||
@ -628,12 +631,15 @@ class assignment_base {
|
||||
set_user_preference('assignment_mailinfo', $mailinfo);
|
||||
}
|
||||
|
||||
if (!($this->validate_and_preprocess_feedback())) {
|
||||
// form was submitted ('Save' or 'Save and next' was pressed, but validation failed)
|
||||
$this->display_submission();
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($mode) {
|
||||
case 'grade': // We are in a main window grading
|
||||
if (!$this->validate_and_preprocess_feedback()) {
|
||||
// validation failed
|
||||
$this->display_submission();
|
||||
} else if ($submission = $this->process_feedback()) {
|
||||
if ($submission = $this->process_feedback()) {
|
||||
$this->display_submissions(get_string('changessaved'));
|
||||
} else {
|
||||
$this->display_submissions();
|
||||
@ -747,11 +753,7 @@ 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 (!$this->validate_and_preprocess_feedback()) {
|
||||
// validation failed
|
||||
$this->display_submission();
|
||||
break;
|
||||
} else if ($submission = $this->process_feedback()) {
|
||||
if ($submission = $this->process_feedback()) {
|
||||
//print_heading(get_string('changessaved'));
|
||||
//$extra_javascript = $this->update_main_listing($submission);
|
||||
}
|
||||
@ -925,7 +927,7 @@ class assignment_base {
|
||||
* @param string $extra_javascript
|
||||
*/
|
||||
function display_submission($offset=-1,$userid =-1, $display=true) {
|
||||
global $CFG, $DB, $PAGE, $OUTPUT;
|
||||
global $CFG, $DB, $PAGE, $OUTPUT, $USER;
|
||||
require_once($CFG->libdir.'/gradelib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
require_once("$CFG->dirroot/repository/lib.php");
|
||||
@ -1046,41 +1048,12 @@ 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');
|
||||
if ($gradingmethod = $gradingman->get_active_method()) {
|
||||
$controller = $gradingman->get_controller($gradingmethod);
|
||||
if ($controller->is_form_available()) {
|
||||
if (empty($submission->id)) {
|
||||
$mformdata->advancedgradingenabled = true;
|
||||
$mformdata->advancedgradingwidget = get_string('noitemid', 'core_grading');
|
||||
} else {
|
||||
$gradingrenderer = $controller->prepare_renderer($PAGE);
|
||||
if ($this->assignment->grade < 0) {
|
||||
$options = array(
|
||||
'displayas' => 'scale',
|
||||
'scaleid' => -$this->assignment->grade);
|
||||
} else {
|
||||
$options = array(
|
||||
'displayas' => 'grade',
|
||||
'maxgrade' => $this->assignment->grade,
|
||||
'decimals' => 0);
|
||||
}
|
||||
$gradingwidget = $controller->make_grading_widget($USER->id, $submission->id, $options);
|
||||
if ($gradingwidget instanceof renderable) {
|
||||
$mformdata->advancedgradingenabled = true;
|
||||
$mformdata->advancedgradingwidget = $gradingrenderer->render($gradingwidget);
|
||||
}
|
||||
}
|
||||
} 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
|
||||
// we create a submission if it does not exist yet because we need submission->id for grading
|
||||
$mformdata->submission = $this->get_submission($user->id, true);
|
||||
}
|
||||
$mformdata->advancedgradingcontroller = $controller;
|
||||
$mformdata->advancedgradinginstance = $controller->create_instance($USER->id, $mformdata->submission->id);
|
||||
}
|
||||
|
||||
$submitform = new mod_assignment_grading_form( null, $mformdata );
|
||||
@ -1591,28 +1564,35 @@ class assignment_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the submitted form and returns false if validation did not pass.
|
||||
* If the form was cancelled ('Cancel' or 'Next' was pressed), call cancel method
|
||||
* from advanced grading (if applicable) and returns true
|
||||
* If the form was submitted, validates it and returns false if validation did not pass.
|
||||
* If validation passes, preprocess advanced grading (if applicable) and returns true.
|
||||
*/
|
||||
function validate_and_preprocess_feedback() {
|
||||
global $USER;
|
||||
if (!$feedback = data_submitted()) {
|
||||
if (!($feedback = data_submitted()) || !isset($feedback->userid) || !isset($feedback->offset)) {
|
||||
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()) {
|
||||
$gradinginstance = $mform->use_advanced_grading();
|
||||
if (optional_param('cancel', false, PARAM_BOOL) || optional_param('next', false, PARAM_BOOL)) {
|
||||
// form was cancelled
|
||||
if ($gradinginstance) {
|
||||
$gradinginstance->cancel();
|
||||
}
|
||||
} else if ($mform->is_submitted()) {
|
||||
// form was submitted (= a submit button other than 'cancel' or 'next' has been clicked)
|
||||
if (!$mform->is_validated()) {
|
||||
return false;
|
||||
}
|
||||
// preprocess advanced grading here
|
||||
if ($controller = $mform->use_advanced_grading()) {
|
||||
if ($gradinginstance) {
|
||||
$data = $mform->get_data();
|
||||
// TODO find better way to find submission id
|
||||
$submission = $this->get_submission($userid);
|
||||
$_POST['xgrade'] = $controller->save_and_get_grade($USER->id /* TODO */, $submission->id, $data->advancedgrading);
|
||||
$_POST['xgrade'] = $gradinginstance->submit_and_get_grade($data->advancedgrading);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -2300,8 +2280,8 @@ class mod_assignment_grading_form extends moodleform {
|
||||
global $OUTPUT;
|
||||
$mform =& $this->_form;
|
||||
|
||||
if (isset($this->_customdata->advancedgradingcontroller)) {
|
||||
$this->use_advanced_grading($this->_customdata->advancedgradingcontroller);
|
||||
if (isset($this->_customdata->advancedgradinginstance)) {
|
||||
$this->use_advanced_grading($this->_customdata->advancedgradinginstance);
|
||||
}
|
||||
|
||||
$formattr = $mform->getAttributes();
|
||||
@ -2349,17 +2329,17 @@ class mod_assignment_grading_form extends moodleform {
|
||||
|
||||
}
|
||||
|
||||
private $_advancegradingcontroller;
|
||||
private $advancegradinginstance;
|
||||
/**
|
||||
* Gets or sets the controller for advanced grading
|
||||
* Gets or sets the instance for advanced grading
|
||||
*
|
||||
* @param <type> $controller
|
||||
* @param gradingform_instance $gradinginstance
|
||||
*/
|
||||
public function use_advanced_grading($controller = false) {
|
||||
if ($controller !== false) {
|
||||
$this->_advancegradingcontroller = $controller;
|
||||
public function use_advanced_grading($gradinginstance = false) {
|
||||
if ($gradinginstance !== false) {
|
||||
$this->advancegradinginstance = $gradinginstance;
|
||||
}
|
||||
return $this->_advancegradingcontroller;
|
||||
return $this->advancegradinginstance;
|
||||
}
|
||||
|
||||
function add_grades_section() {
|
||||
@ -2372,10 +2352,8 @@ class mod_assignment_grading_form extends moodleform {
|
||||
|
||||
$mform->addElement('header', 'Grades', get_string('grades', 'grades'));
|
||||
|
||||
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));
|
||||
if ($gradinginstance = $this->use_advanced_grading()) {
|
||||
$mform->addElement('grading', 'advancedgrading', get_string('grade').':', array('gradinginstance' => $gradinginstance));
|
||||
} else {
|
||||
// use simple direct grading
|
||||
$grademenu = make_grades_menu($this->_customdata->assignment->grade);
|
||||
|
Loading…
x
Reference in New Issue
Block a user