Yay! Saving dimensions works
Cooking dimension editor's raw data is done by the strategy class.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for (some of) mod/workshop/grading/accumulative/strategy.php
|
||||
*
|
||||
* @package mod-workshop
|
||||
* @copyright 2009 David Mudrak <[email protected]>
|
||||
* @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,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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['dimensiondescription'] = 'Description';
|
||||
$string['dimensionnumberaccumulative'] = 'Aspect $a';
|
||||
$string['dimensionweight'] = 'Weight';
|
||||
$string['editgradingform'] = 'Edit grading form';
|
||||
$string['editinggradingform'] = 'Editing grading form';
|
||||
$string['dimensiondescription'] = 'Description';
|
||||
$string['dimensionweight'] = 'Weight';
|
||||
$string['dimensionnumberaccumulative'] = 'Aspect $a';
|
||||
$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[''] = '';
|
||||
|
||||
Reference in New Issue
Block a user