From: David Mudrak Date: Mon, 4 Jan 2010 17:44:52 +0000 (+0000) Subject: First drafts of assessment support X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=0968b1a3935d71cee446e8c842f5cc9403f9db40;p=moodle.git First drafts of assessment support --- diff --git a/mod/workshop/assessment.php b/mod/workshop/assessment.php new file mode 100644 index 0000000000..34c9f68d8f --- /dev/null +++ b/mod/workshop/assessment.php @@ -0,0 +1,149 @@ +. + + +/** + * Assess a submission or preview the assessment form + * + * Displays an assessment form and saves the grades given by current user (reviewer) + * for the dimensions. + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); +//require_once(dirname(__FILE__).'/lib.php'); +require_once(dirname(__FILE__).'/locallib.php'); + +if ($preview = optional_param('preview', 0, PARAM_INT)) { + $mode = 'preview'; + if (!$cm = get_coursemodule_from_id('workshop', $preview)) { + print_error('invalidcoursemodule'); + } + if (!$course = $DB->get_record('course', array('id' => $cm->course))) { + print_error('coursemisconf'); + } + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { + print_error('err_invalidworkshopid', 'workshop'); + } + $submission = new stdClass(); + $assessment = new stdClass(); +} else { + $mode = 'assessment'; + $assessmentid = required_param('asid', PARAM_INT); // assessment id + if (!$assessment = $DB->get_record('workshop_assessments', array('id' => $assessmentid))) { + print_error('err_unknownassessment', 'workshop'); + } + if (!$submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid))) { + print_error('err_unknownsubmission', 'workshop'); + } + if (!$workshop = $DB->get_record('workshop', array('id' => $submission->workshopid))) { + print_error('err_invalidworkshopid', 'workshop'); + } + if (!$cm = get_coursemodule_from_instance('workshop', $workshop->id, $workshop->course)) { + print_error('invalidcoursemodule'); + } + if (!$course = $DB->get_record('course', array('id' => $cm->course))) { + print_error('coursemisconf'); + } +} + +require_login($course, false, $cm); + +$context = get_context_instance(CONTEXT_MODULE, $cm->id); + +if (isguestuser()) { + print_error('err_noguests', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); +} + +// where should the user be sent after closing the assessment form +$returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; +// the URL of this handler +if ($mode == 'preview') { + $selfurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?preview={$cm->id}"; +} elseif ($mode == 'assessment') { + $selfurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?asid={$assessment->id}"; +} +// the URL to edit this assessment form +$editurl = "{$CFG->wwwroot}/mod/workshop/editform.php?cmid={$cm->id}"; + +// load the grading strategy logic +$strategy = workshop_strategy_instance($workshop); + +// load the assessment form definition from the database +// this must be called before get_assessment_form() where we have to know +// the number of repeating fieldsets + +//todo $formdata = $strategy->load_assessment($assessment); + + + +// load the form to edit the grading strategy dimensions +$mform = $strategy->get_assessment_form($selfurl, $mode); + +// initialize form data +//todo $mform->set_data($formdata); + +if ($mform->is_cancelled()) { + redirect($returnurl); +} elseif ($data = $mform->get_data()) { + if (isset($data->backtoeditform)) { + redirect($editurl); + } + $strategy->save_assessment($data); + if (isset($data->saveandclose)) { + redirect($returnurl); + } else { + // save and continue - redirect to self to prevent data being re-posted by pressing "Reload" + redirect($selfurl); + } +} + +// build the navigation and the header +$navlinks = array(); +$navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), + 'link' => "index.php?id=$course->id", + 'type' => 'activity'); +$navlinks[] = array('name' => format_string($workshop->name), + 'link' => "view.php?id=$cm->id", + 'type' => 'activityinstance'); +if ($mode == 'preview') { + $navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'), + 'link' => $editurl, + 'type' => 'title'); + $navlinks[] = array('name' => get_string('previewassessmentform', 'workshop'), + 'link' => '', + 'type' => 'title'); +} elseif ($mode == 'assessment') { + $navlinks[] = array('name' => get_string('assessingsubmission', 'workshop'), + 'link' => '', + 'type' => 'title'); +} +$navigation = build_navigation($navlinks); + +// OUTPUT STARTS HERE + +print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, '', navmenu($course, $cm)); + +print_heading(get_string('assessmentform', 'workshop')); + +$mform->display(); + +/// Finish the page +print_footer($course); diff --git a/mod/workshop/editform.php b/mod/workshop/editform.php index bac7e319a0..b675ae06bf 100644 --- a/mod/workshop/editform.php +++ b/mod/workshop/editform.php @@ -26,6 +26,7 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); require_once(dirname(__FILE__).'/lib.php'); +require_once(dirname(__FILE__).'/locallib.php'); $cmid = required_param('cmid', PARAM_INT); // course module id @@ -42,27 +43,22 @@ require_login($course, false, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); if (isguestuser()) { - print_error('guestnoedit', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); + print_error('err_noguests', 'workshop', "$CFG->wwwroot/mod/workshop/view.php?id=$cmid"); } if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { - print_error('invalidid', 'workshop'); + print_error('err_invalidworkshopid', 'workshop'); } // where should the user be sent after closing the editing form -$returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; +$returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; // the URL of this editing form -$selfurl = "{$CFG->wwwroot}/mod/workshop/editform.php?cmid={$cm->id}"; +$selfurl = "{$CFG->wwwroot}/mod/workshop/editform.php?cmid={$cm->id}"; +// the URL to preview the assessment form +$previewurl = "{$CFG->wwwroot}/mod/workshop/assessment.php?preview={$cm->id}"; // load the grading strategy logic -$strategylib = dirname(__FILE__) . '/grading/' . $workshop->strategy . '/strategy.php'; -if (file_exists($strategylib)) { - require_once($strategylib); -} else { - print_error('errloadingstrategylib', 'workshop', $returnurl); -} -$classname = 'workshop_' . $workshop->strategy . '_strategy'; -$strategy = new $classname($workshop); +$strategy = workshop_strategy_instance($workshop); // load the assessment form definition from the database // this must be called before get_edit_strategy_form() where we have to know @@ -81,7 +77,10 @@ if ($mform->is_cancelled()) { $strategy->save_form($data); if (isset($data->saveandclose)) { redirect($returnurl); + } elseif (isset($data->saveandpreview)) { + redirect($previewurl); } else { + // save and continue - redirect to self to prevent data being re-posted by pressing "Reload" redirect($selfurl); } } @@ -94,15 +93,14 @@ $navlinks[] = array('name' => get_string('modulenameplural', 'workshop'), $navlinks[] = array('name' => format_string($workshop->name), 'link' => "view.php?id=$cm->id", 'type' => 'activityinstance'); -$navlinks[] = array('name' => get_string('editinggradingform', 'workshop'), +$navlinks[] = array('name' => get_string('editingassessmentform', 'workshop'), 'link' => '', 'type' => 'title'); $navigation = build_navigation($navlinks); // OUTPUT STARTS HERE -print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, - update_module_button($cm->id, $course->id, get_string('modulename', 'workshop')), navmenu($course, $cm)); +print_header_simple(format_string($workshop->name), '', $navigation, '', '', true, '', navmenu($course, $cm)); print_heading(get_string('strategy' . $workshop->strategy, 'workshop')); diff --git a/mod/workshop/grading/accumulative/assessment_form.php b/mod/workshop/grading/accumulative/assessment_form.php new file mode 100644 index 0000000000..f4b10bd21b --- /dev/null +++ b/mod/workshop/grading/accumulative/assessment_form.php @@ -0,0 +1,76 @@ +. + + +/** + * This file defines an mform to assess a submission by accumulative grading strategy + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +//require_once(dirname(dirname(dirname(__FILE__))).'/lib.php'); // module library +require_once(dirname(dirname(__FILE__)).'/assessment_form.php'); // parent class definition + + +/** + * Class representing a form for assessing submissions by accumulative grading strategy + * + * @uses moodleform + */ +class workshop_accumulative_assessment_form extends workshop_assessment_form { + + /** + * Define the elements to be displayed at the form + * + * Called by the parent::definition() + * + * @access protected + * @return void + */ + protected function definition_inner(&$mform) { + + for ($i = 0; $i < $this->strategy->get_number_of_dimensions(); $i++) { + + // dimension header + $mform->addElement('header', "dimensionhdr[$i]", + str_replace('{no}', $i+1, get_string('dimensionnumberaccumulative', 'workshop', '{no}'))); + + // dimension description + $desc = '
' . "\n"; + $desc .= format_text($this->fields["description[$i]"], $this->fields["descriptionformat[$i]"]); + $desc .= "\n
"; + $mform->addElement('html', $desc); + + // grade for this aspect + $label = 'Grade'; // todo + $options = array(10,9,8,7,6,5,4,3,2,1,0); // todo + $mform->addElement('select', "grade[$i]", $label, $options); + + // comment + $label = 'Comment'; //todo + $mform->addElement('htmleditor', "comment[$i]", $label, array()); + + } + + } + + +} diff --git a/mod/workshop/grading/assessment_form.php b/mod/workshop/grading/assessment_form.php new file mode 100644 index 0000000000..bedb1d4738 --- /dev/null +++ b/mod/workshop/grading/assessment_form.php @@ -0,0 +1,98 @@ +. + + +/** + * This file defines a base class for all assessment forms + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir . '/formslib.php'); // parent class definition + + +/** + * Base class for all assessment forms + * + * This defines the common fields that all assessment forms need. + * Strategies should define their own class that inherits from this one, and + * implements the definition_inner() method. + * + * @uses moodleform + */ +class workshop_assessment_form extends moodleform { + + /** object Strategy logic instance */ + protected $strategy; + + /** array Assessment form fields defined by teacher */ + protected $fields = array(); + + /** string The mode of the form: "preview" or "assessment" */ + protected $mode = 'preview'; + + /** + * Add the fields that are common for all grading strategies. + * + * If the strategy does not support all these fields, then you can override + * this method and remove the ones you don't want with + * $mform->removeElement(). + * Strategy subclassess should define their own fields in definition_inner() + * + * @access public + * @return void + */ + public function definition() { + global $CFG; + + $mform = $this->_form; + $this->strategy = $this->_customdata['strategy']; + $this->fields = (array)$this->_customdata['fields']; + $this->mode = $this->_customdata['mode']; + + $mform->addElement('hidden', 'strategyname', $this->strategy->name); + + $this->definition_inner($mform); + + $buttonarray = array(); + if ($this->mode == 'preview') { + $buttonarray[] = &$mform->createElement('submit', 'backtoeditform', get_string('backtoeditform', 'workshop')); + } + if ($this->mode == 'assessment') { + $buttonarray[] = &$mform->createElement('submit', 'saveandcontinue', get_string('saveandcontinue', 'workshop')); + $buttonarray[] = &$mform->createElement('submit', 'saveandclose', get_string('saveandclose', 'workshop')); + } + $buttonarray[] = &$mform->createElement('cancel'); + $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); + $mform->closeHeaderBefore('buttonar'); + } + + + /** + * Add any strategy specific form fields. + * + * @param object $mform the form being built. + */ + protected function definition_inner(&$mform) { + // By default, do nothing. + } + +} diff --git a/mod/workshop/grading/edit_form.php b/mod/workshop/grading/edit_form.php index 36dc6613fe..ac5ebabfdf 100644 --- a/mod/workshop/grading/edit_form.php +++ b/mod/workshop/grading/edit_form.php @@ -70,8 +70,9 @@ class workshop_edit_strategy_form extends moodleform { } $buttonarray = array(); - $buttonarray[] = &$mform->createElement('submit', 'saveandclose', get_string('saveandclose', 'workshop')); $buttonarray[] = &$mform->createElement('submit', 'saveandcontinue', get_string('saveandcontinue', 'workshop')); + $buttonarray[] = &$mform->createElement('submit', 'saveandpreview', get_string('saveandpreview', 'workshop')); + $buttonarray[] = &$mform->createElement('submit', 'saveandclose', get_string('saveandclose', 'workshop')); $buttonarray[] = &$mform->createElement('cancel'); $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); $mform->closeHeaderBefore('buttonar'); diff --git a/mod/workshop/grading/strategy.php b/mod/workshop/grading/strategy.php index 47ed371b80..22afba2436 100644 --- a/mod/workshop/grading/strategy.php +++ b/mod/workshop/grading/strategy.php @@ -157,5 +157,37 @@ abstract class workshop_base_strategy implements workshop_strategy { } + /** + * Factory method returning an instance of an assessment form + * + * By default, the class is defined in grading/{strategy}/assessment_form.php and is named + * workshop_{strategy}_assessment_form + * + * @param string $actionurl URL of form handler, defaults to auto detect the current url + * @param string $mode Mode to open the form in: preview/assessment + */ + public function get_assessment_form($actionurl=null, $mode='preview') { + global $CFG; // needed because the included files use it + + $assessmentform = dirname(__FILE__) . '/' . $this->name . '/assessment_form.php'; + if (is_readable($assessmentform)) { + require_once($assessmentform); + } else { + throw new moodle_exception('errloadingassessmentform', 'workshop'); + } + $classname = 'workshop_' . $this->name . '_assessment_form'; + + $customdata = new stdClass; + $customdata = array( + 'strategy' => $this, + 'fields' => $this->load_form(), + 'mode' => $mode, + ); + $attributes = array('class' => 'assessmentform'); + + return new $classname($actionurl, $customdata, 'post', '', $attributes); + + } + } diff --git a/mod/workshop/lang/en_utf8/workshop.php b/mod/workshop/lang/en_utf8/workshop.php index 3ff68f25b3..a87b2fe835 100644 --- a/mod/workshop/lang/en_utf8/workshop.php +++ b/mod/workshop/lang/en_utf8/workshop.php @@ -54,9 +54,7 @@ $string[''] = ''; $string[''] = ''; $string[''] = ''; $string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; +$string['assessingsubmission'] = 'Assessing submission'; $string['accesscontrol'] = 'Access control'; $string['addmoredimensionsaccumulative'] = 'Blanks for $a more aspects'; $string['addmoredimensionsnoerrors'] = 'Blanks for $a more assertions'; @@ -70,10 +68,12 @@ $string['anonymityreviewers'] = 'Authors can\'t see reviewers\' names'; $string['assessallexamples'] = 'Assess all examples'; $string['assessmentcomps'] = 'Required level of assessments similarity'; $string['assessmentend'] = 'End of assessment phase'; +$string['assessmentform'] = 'Assessment form'; $string['assessmentsettings'] = 'Assessment settings'; $string['assessmentstart'] = 'Start of assessment phase'; $string['assesswosubmission'] = 'Assess without submission'; $string['assesswosubmissiondesc'] = 'Users can assess peers even without their own submission'; +$string['backtoeditform'] = 'Back to editing form'; $string['comparisonhigh'] = 'High'; $string['comparisonlow'] = 'Low'; $string['comparisonnormal'] = 'Normal'; @@ -94,8 +94,7 @@ $string['dimensiondescription'] = 'Description'; $string['dimensionnumberaccumulative'] = 'Aspect $a'; $string['dimensionnumbernoerrors'] = 'Assertion $a'; $string['dimensionweight'] = 'Weight'; -$string['editgradingform'] = 'Edit grading form'; -$string['editinggradingform'] = 'Editing grading form'; +$string['editingassessmentform'] = 'Editing assessment form'; $string['editingsubmission'] = 'Editing submission'; $string['err_removegrademappings'] = 'Unable to remove the unused grade mappings'; $string['examplesbeforeassessment'] = 'Examples are available after own submission and must be assessed before peer/self assessment phase'; @@ -124,10 +123,12 @@ $string['noerrorsmaperror'] = 'Number of errors is less than or equals'; $string['noerrorsmapgrade'] = 'Grade for submission'; $string['nsassessments'] = 'Number of required assessments of other users\' work'; $string['percents'] = '$a%'; +$string['previewassessmentform'] = 'Preview'; $string['releasegrades'] = 'Push final grades into the gradebook'; $string['requirepassword'] = 'Require password'; $string['saveandclose'] = 'Save and close'; $string['saveandcontinue'] = 'Save and continue editing'; +$string['saveandpreview'] = 'Save and preview'; $string['strategyaccumulative'] = 'Accumulative grading'; $string['strategy'] = 'Grading strategy'; $string['strategynoerrors'] = 'Number of errors'; diff --git a/mod/workshop/locallib.php b/mod/workshop/locallib.php index bf546e6c98..9fe1d30c3e 100644 --- a/mod/workshop/locallib.php +++ b/mod/workshop/locallib.php @@ -29,6 +29,25 @@ defined('MOODLE_INTERNAL') || die(); +function workshop_strategy_instance($workshop) { + /** static variable to hold the singleton */ + static $instance = null; + + if (is_null($instance)) { + $strategylib = dirname(__FILE__) . '/grading/' . $workshop->strategy . '/strategy.php'; + if (is_readable($strategylib)) { + require_once($strategylib); + } else { + throw new moodle_exception('missingstrategy', 'workshop'); + } + $classname = 'workshop_' . $workshop->strategy . '_strategy'; + $instance = new $classname($workshop); + } + + return $instance; +} + + /** * Return the user's submission record in the given workshop *