From: David Mudrak Date: Mon, 4 Jan 2010 17:37:31 +0000 (+0000) Subject: Yay! Saving dimensions works X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=9277982f0f5d86d10f7cf750c01dbe36ddea9efe;p=moodle.git Yay! Saving dimensions works Cooking dimension editor's raw data is done by the strategy class. --- diff --git a/mod/workshop/editgradingform.php b/mod/workshop/editgradingform.php index 0a9660907d..11fc39478f 100644 --- a/mod/workshop/editgradingform.php +++ b/mod/workshop/editgradingform.php @@ -62,8 +62,9 @@ require_login($course, true, $cm); add_to_log($course->id, "workshop", "editgradingform", "editgradingform.php?id=$cm->id", "$workshop->id"); -// where should the user be sent in case of error of canceling +// where should the user be sent after closing the editing form $returnurl = "{$CFG->wwwroot}/mod/workshop/view.php?id={$cm->id}"; +// the URL of this editing form $selfurl = "{$CFG->wwwroot}/mod/workshop/editgradingform.php?id={$cm->id}"; // load the grading strategy logic @@ -92,7 +93,12 @@ $mform->set_data($formdata); if ($mform->is_cancelled()) { redirect($returnurl); } elseif ($data = $mform->get_data()) { - print_object($data); die(); + $strategy->save_dimensions($data); + if (isset($data->saveandclose)) { + redirect($returnurl); + } else { + redirect($selfurl); + } } // build the navigation and the header diff --git a/mod/workshop/grading/accumulative/gradingform.php b/mod/workshop/grading/accumulative/gradingform.php index 284241a211..d467730632 100644 --- a/mod/workshop/grading/accumulative/gradingform.php +++ b/mod/workshop/grading/accumulative/gradingform.php @@ -24,11 +24,10 @@ * @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 -} +defined('MOODLE_INTERNAL') || die(); -require_once(dirname(dirname(__FILE__)).'/gradingform.php'); // parent class definition +require_once(dirname(dirname(dirname(__FILE__))).'/lib.php'); // module library +require_once(dirname(dirname(__FILE__)).'/gradingform.php'); // parent class definition /** @@ -53,9 +52,10 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo $repeated = array(); $repeated[] =& $mform->createElement('hidden', 'dimensionid', 0); - $repeated[] =& $mform->createElement('header', 'dimension', get_string('dimensionnumberaccumulative', 'workshop', '{no}')); - $repeated[] =& $mform->createElement('textarea', 'description', - get_string('dimensiondescription', 'workshop'), array('cols'=>60)); + $repeated[] =& $mform->createElement('header', 'dimension', + get_string('dimensionnumberaccumulative', 'workshop', '{no}')); + $repeated[] =& $mform->createElement('htmleditor', 'description', + get_string('dimensiondescription', 'workshop'), array()); $repeated[] =& $mform->createElement('select', 'grade', get_string('grade'), $gradeoptions); $repeated[] =& $mform->createElement('select', 'weight', get_string('dimensionweight', 'workshop'), $weights); @@ -73,21 +73,4 @@ class workshop_edit_accumulative_strategy_form extends workshop_edit_strategy_fo } - /** - * Return the mapping of the db fields to the form fields for every dimension of assessment - * - * @access protected - * @return array Array ['field_db_name' => 'field_form_name'] - */ - protected function get_dimension_fieldnames() { - return array( - 'id' => 'dimensionid', - 'description' => 'description', - 'descriptionformat' => 'descriptionformat', - 'grade' => 'grade', - 'weight' => 'weight', - ); - } - - } diff --git a/mod/workshop/grading/accumulative/simpletest/teststrategy.php b/mod/workshop/grading/accumulative/simpletest/teststrategy.php new file mode 100644 index 0000000000..0ffcf7f5d6 --- /dev/null +++ b/mod/workshop/grading/accumulative/simpletest/teststrategy.php @@ -0,0 +1,114 @@ +. + + +/** + * Unit tests for (some of) mod/workshop/grading/accumulative/strategy.php + * + * @package mod-workshop + * @copyright 2009 David Mudrak + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +// Include the code to test +require_once($CFG->dirroot . '/mod/workshop/grading/accumulative/strategy.php'); + + +/** + * Test subclass that makes all the protected methods we want to test public + */ +class testable_workshop_accumulative_strategy extends workshop_accumulative_strategy { + + public function cook_form_data($raw) { + return parent::cook_form_data($raw); + } +} + + +class workshop_accumulative_strategy_test extends UnitTestCase { + + /** workshop instance emulation */ + protected $workshop; + + /** instance of the strategy logic class being tested */ + protected $strategy; + + /** this emulates data returned by get_data() of a submitted strategy edit form */ + protected $rawdata; + + /** setup testing environment */ + public function setUp() { + + $this->workshop = new stdClass; + $this->workshop->id = 42; + $this->workshop->strategy = 'accumulative'; + + $this->strategy = new testable_workshop_accumulative_strategy($this->workshop); + + // emulate a form with 5 dimensions. The first three are already in DB, the forth is new and the + // fifth is left empty + $this->rawdata = new stdClass; + $this->rawdata->workshopid = 42; + $this->rawdata->strategy = 'accumulative'; + $this->rawdata->numofdimensions = 5; + $this->rawdata->dimensionid = array(0 => 3, 1=> 2, 2 => 1, 3 => 0, 4 => 0); + $this->rawdata->description = array(0 => 'First', 1 => 'Second', 2 => 'Third', 3 => 'Forth', 4 => ''); + $this->rawdata->descriptionformat = array(0 => 1, 1 => 1, 2 => 1, 3 => 1, 4 => 1); + $this->rawdata->grade = array(0 => 10, 1 => 5, 2 => 5, 3 => 2, 4 => 10); + $this->rawdata->weight = array(0 => 1, 1 => 1, 2 => 2, 3 => 2, 4 => 1); + } + + public function tearDown() { + $this->strategy = null; + } + + public function test_cook_form_data() { + + $cooked = $this->strategy->cook_form_data($this->rawdata); + $this->assertIsA($cooked, 'Array'); + $this->assertEqual($cooked[2], (object)array( + 'id' => 1, + 'workshopid' => 42, + 'sort' => 3, + 'description' => 'Third', + 'descriptionformat' => 1, + 'grade' => 5, + 'weight' => 2, + )); + $this->assertEqual($cooked[3], (object)array( + 'id' => 0, + 'workshopid' => 42, + 'sort' => 4, + 'description' => 'Forth', + 'descriptionformat' => 1, + 'grade' => 2, + 'weight' => 2, + )); + $this->assertEqual($cooked[4], (object)array( + 'id' => 0, + 'workshopid' => 42, + 'sort' => 5, + 'description' => '', + 'descriptionformat' => 1, + 'grade' => 10, + 'weight' => 1, + )); + } + +} diff --git a/mod/workshop/grading/accumulative/strategy.php b/mod/workshop/grading/accumulative/strategy.php index f9a63d3ada..0ecfd81d0d 100644 --- a/mod/workshop/grading/accumulative/strategy.php +++ b/mod/workshop/grading/accumulative/strategy.php @@ -36,4 +36,20 @@ require_once(dirname(dirname(__FILE__)) . '/strategy.php'); // parent class */ class workshop_accumulative_strategy extends workshop_strategy { + /** + * Mapping of the db fields to the form fields for every dimension of assessment + * + * @return array Array ['field_db_name' => 'field_form_name'] + */ + public function map_dimension_fieldnames() { + return array( + 'id' => 'dimensionid', + 'description' => 'description', + 'descriptionformat' => 'descriptionformat', + 'grade' => 'grade', + 'weight' => 'weight', + ); + } + + } diff --git a/mod/workshop/grading/gradingform.php b/mod/workshop/grading/gradingform.php index 4aa732ddfc..9553dafff9 100644 --- a/mod/workshop/grading/gradingform.php +++ b/mod/workshop/grading/gradingform.php @@ -24,9 +24,7 @@ * @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 -} +defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/formslib.php'); // parent class definition @@ -42,26 +40,26 @@ require_once($CFG->libdir . '/formslib.php'); // parent class definition */ class workshop_edit_strategy_form extends moodleform { - /** - * Number of dimensions that are populated from DB - * - * @var mixed - * @access protected - */ + /** strategy logic instance that this class is editor of */ + protected $strategy; + + /** number of dimensions that are populated from DB */ protected $numofdimensions; /** * Constructor * + * @param object $strategy The instance of the strategy logic * @param str $actionurl URL to handle data * @param bool $editable Should the form be editable? * @param int $initialdimensions Number of assessment dimensions that are already filled * @access public * @return void */ - public function __construct($actionurl, $editable=true, $initialdimensions=0) { + public function __construct(workshop_strategy $strategy, $actionurl, $editable=true, $initialdimensions=0) { - $this->numofdimensions = $initialdimensions; + $this->strategy = $strategy; + $this->numofdimensions = $initialdimensions; parent::moodleform($actionurl, null, 'post', '', array('class' => 'editstrategyform'), $editable); } @@ -96,7 +94,8 @@ class workshop_edit_strategy_form extends moodleform { } $buttonarray = array(); - $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges')); + $buttonarray[] = &$mform->createElement('submit', 'saveandclose', get_string('saveandclose', 'workshop')); + $buttonarray[] = &$mform->createElement('submit', 'saveandcontinue', get_string('saveandcontinue', 'workshop')); $buttonarray[] = &$mform->createElement('cancel'); $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); $mform->closeHeaderBefore('buttonar'); @@ -117,7 +116,7 @@ class workshop_edit_strategy_form extends moodleform { * Set the form data before it is displayed * * Strategy plugins should provide the list of fields to be mapped from - * DB record to the form fields in their get_dimension_fieldnames() method + * DB record to the form fields in their map_dimension_fieldnames() method * * @param object $formdata Should contain the array $formdata->dimensions * @access public @@ -130,7 +129,7 @@ class workshop_edit_strategy_form extends moodleform { $key = 0; $default_values = array(); foreach ($formdata->dimensions as $dimension) { - foreach ($this->get_dimension_fieldnames() as $fielddbname => $fieldformname) { + foreach ($this->strategy->map_dimension_fieldnames() as $fielddbname => $fieldformname) { $default_values[$fieldformname . '[' . $key . ']'] = $dimension->$fielddbname; } $key++; @@ -141,14 +140,4 @@ class workshop_edit_strategy_form extends moodleform { } - /** - * Return the mapping of the db fields to the form fields for every assessment dimension - * - * @access protected - * @return array Array ['field_db_name' => 'field_form_name'] - */ - protected function get_dimension_fieldnames() { - return array(); - } - } diff --git a/mod/workshop/grading/strategy.php b/mod/workshop/grading/strategy.php index e820445593..da42ecee66 100644 --- a/mod/workshop/grading/strategy.php +++ b/mod/workshop/grading/strategy.php @@ -24,16 +24,27 @@ * @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 -} - +defined('MOODLE_INTERNAL') || die(); /** * Strategy interface defines all methods that strategy subplugins has to implemens */ interface workshop_strategy_interface { + /** + * Factory method returning an instance of an assessment form editor class + * + * The returned class will probably expand the base workshop_edit_strategy_form + * + * @param string $actionurl URL of the action handler script + * @param boolean $edit Open the form in editing mode + * @param int $nodimensions Number of dimensions to be provided by set_data + * @access public + * @return object The instance of the assessment form editor class + */ + public function get_edit_strategy_form($actionurl, $edit=true, $nodimensions=0); + + /** * Load the assessment dimensions from database * @@ -41,16 +52,30 @@ interface workshop_strategy_interface { * to be evaluated. Each dimension consists of a set of form fields. Strategy-specific information * are saved in workshop_forms_{strategyname} tables. * - * @uses $DB * @access public - * @return void + * @return array Array of database records */ public function load_dimensions(); + + /** + * Save the assessment dimensions into database + * + * Assessment dimension (also know as assessment element) represents one aspect or criterion + * to be evaluated. Each dimension consists of a set of form fields. Strategy-specific information + * are saved in workshop_forms_{strategyname} tables. + * + * @access public + * @return void + */ + public function save_dimensions($data); } /** - * Base class for grading strategy logic. + * Base class for grading strategy logic + * + * This base class implements the default behaviour that should be suitable for the most + * of simple grading strategies. */ class workshop_strategy implements workshop_strategy_interface { @@ -74,6 +99,12 @@ class workshop_strategy implements workshop_strategy_interface { } + /** + * Factory method returning an instance of an assessment form editor class + * + * By default, the class is defined in grading/{strategy}/gradingform.php and is named + * workshop_edit_{strategy}_strategy_form + */ public function get_edit_strategy_form($actionurl, $edit=true, $nodimensions=0) { global $CFG; // needed because the included files use it @@ -85,14 +116,15 @@ class workshop_strategy implements workshop_strategy_interface { } $classname = 'workshop_edit_' . $this->name . '_strategy_form'; - return new $classname($actionurl, $edit, $nodimensions); + return new $classname($this, $actionurl, $edit, $nodimensions); } + /** * Load the assessment dimensions from database * - * This base method just fetches all relevant records from the strategy form table. + * This base method just fetches all relevant records from the main strategy form table. * * @uses $DB * @access public @@ -104,4 +136,74 @@ class workshop_strategy implements workshop_strategy_interface { return $DB->get_records('workshop_forms_' . $this->name, array('workshopid' => $this->_workshop->id), 'sort'); } + + /** + * Save the assessment dimensions into database + * + * This base method saves data into the main strategy form table. If the record->id is null or zero, + * new record is created. If the record->id is not empty, the existing record is updated. Records with + * empty 'description' field are not saved. + * The passed data object are the raw data returned by the get_data(). They must be cooked here. + * + * @uses $DB + * @param object $data Raw data returned by the dimension editor form + * @access public + * @return void + */ + public function save_dimensions($data) { + global $DB; + + $data = $this->cook_form_data($data); + + foreach ($data as $record) { + if (empty($record->description)) { + continue; + } + if (empty($record->id)) { + // new field + $record->id = $DB->insert_record('workshop_forms_' . $this->name, $record); + } else { + // exiting field + $DB->update_record('workshop_forms_' . $this->name, $record); + } + } + } + + + /** + * The default implementation transposes the returned structure + * + * It automatically adds 'sort' column and 'workshopid' column into every record. + * The sorting is done by the order of the returned array and starts with 1. + * + * @param object $raw + * @return void + */ + protected function cook_form_data($raw) { + + $cook = array(); + foreach (array_flip($this->map_dimension_fieldnames()) as $formfield => $dbfield) { + for ($k = 0; $k < $raw->numofdimensions; $k++) { + $cook[$k]->{$dbfield} = isset($raw->{$formfield}[$k]) ? $raw->{$formfield}[$k] : null; + $cook[$k]->sort = $k + 1; + $cook[$k]->workshopid = $raw->workshopid; + } + } + return $cook; + } + + + /** + * Return the mapping of the db fields to the form fields for every assessment dimension + * + * This must be public because it is also used by the dimensions editor class. + * + * @return array Array ['field_db_name' => 'field_form_name'] + */ + public function map_dimension_fieldnames() { + return array(); + } + + + } diff --git a/mod/workshop/lang/en_utf8/workshop.php b/mod/workshop/lang/en_utf8/workshop.php index 346acbc2ec..ac22488f44 100644 --- a/mod/workshop/lang/en_utf8/workshop.php +++ b/mod/workshop/lang/en_utf8/workshop.php @@ -24,6 +24,21 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; +$string[''] = ''; $string['accesscontrol'] = 'Access control'; $string['addmoredimensionsaccumulative'] = 'Blanks for $a more aspects'; $string['agreeassessments'] = 'Assessments must be agreed'; @@ -54,11 +69,11 @@ $string['configmaxbytes'] = 'Default maximum submission file size for all worksh $string['confignexassessments'] = 'Default number of examples to be reviewed by a user in the example assessment phase'; $string['confignsassessments'] = 'Default number of allocated submissions to be reviewed by a user in the assessment phase'; $string['configstrategy'] = 'Default grading strategy for workshops'; -$string['editgradingform'] = 'Edit grading form'; -$string['editinggradingform'] = 'Editing grading form'; $string['dimensiondescription'] = 'Description'; -$string['dimensionweight'] = 'Weight'; $string['dimensionnumberaccumulative'] = 'Aspect $a'; +$string['dimensionweight'] = 'Weight'; +$string['editgradingform'] = 'Edit grading form'; +$string['editinggradingform'] = 'Editing grading form'; $string['examplesbeforeassessment'] = 'Examples are available after own submission and must be assessed before peer/self assessment phase'; $string['examplesbeforesubmission'] = 'Examples must be assessed before own submission'; $string['examplesmode'] = 'Mode of examples assessment'; @@ -79,6 +94,8 @@ $string['nexassessments'] = 'Number of required assessments of examples'; $string['nsassessments'] = 'Number of required assessments of other users\' work'; $string['releasegrades'] = 'Push final grades into the gradebook'; $string['requirepassword'] = 'Require password'; +$string['saveandclose'] = 'Save and close'; +$string['saveandcontinue'] = 'Save and continue'; $string['strategyaccumulative'] = 'Accumulative grading'; $string['strategyerrorbanded'] = 'Error banded grading'; $string['strategy'] = 'Grading strategy'; @@ -96,18 +113,3 @@ $string['useselfassessmentdesc'] = 'Users perform self assessment of their own w $string['useselfassessment'] = 'Use self assessment'; $string['workshopfeatures'] = 'Workshop features'; $string['workshopname'] = 'Workshop name'; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = ''; -$string[''] = '';