Skip to content

Commit

Permalink
Saving a form as a public template
Browse files Browse the repository at this point in the history
There is a new API method get_definition_copy() that is expected to
return the definition structure as if the form was written from scratch
via the editor. Such a prepared structure is passed to
a controller's update_definition() method in the new target area.

The same mechanism will be used for copying definitions from a shared
area to a normal gradable area.
  • Loading branch information
mudrd8mz committed Oct 18, 2011
1 parent 71bd9d2 commit fde3380
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 19 deletions.
30 changes: 30 additions & 0 deletions grade/grading/form/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,36 @@ public function get_definition() {
return $this->definition;
}

/**
* Returns the form definition suitable for cloning into another area
*
* @param gradingform_controller $target the controller of the new copy
* @return stdClass definition structure to pass to the target's {@link update_definition()}
*/
public function get_definition_copy(gradingform_controller $target) {

if (get_class($this) != get_class($target)) {
throw new coding_exception('The source and copy controller mismatch');
}

if ($target->is_form_defined()) {
throw new coding_exception('The target controller already contains a form definition');
}

$old = $this->get_definition();
// keep our id
$new = new stdClass();
$new->copiedfromid = $old->id;
$new->name = $old->name;
// once we support files embedded into the description, we will want to
// relink them into the new file area here (that is why we accept $target)
$new->description = $old->description;
$new->descriptionformat = $old->descriptionformat;
$new->options = $old->options;

return $new;
}

/**
* Saves the defintion data into the database
*
Expand Down
34 changes: 34 additions & 0 deletions grade/grading/form/rubric/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,39 @@ public function get_definition_for_editing() {
return $properties;
}

/**
* Returns the form definition suitable for cloning into another area
*
* @see parent::get_definition_copy()
* @param gradingform_controller $target the controller of the new copy
* @return stdClass definition structure to pass to the target's {@link update_definition()}
*/
public function get_definition_copy(gradingform_controller $target) {

$new = parent::get_definition_copy($target);
$old = $this->get_definition();
$new->rubric_criteria = array();
$newcritid = 1;
$newlevid = 1;
foreach ($old->rubric_criteria as $oldcritid => $oldcrit) {
unset($oldcrit['id']);
if (isset($oldcrit['levels'])) {
foreach ($oldcrit['levels'] as $oldlevid => $oldlev) {
unset($oldlev['id']);
$oldcrit['levels']['NEWID'.$newlevid] = $oldlev;
unset($oldcrit['levels'][$oldlevid]);
$newlevid++;
}
} else {
$oldcrit['levels'] = array();
}
$new->rubric_criteria['NEWID'.$newcritid] = $oldcrit;
$newcritid++;
}

return $new;
}

public function get_grading($raterid, $itemid) {
global $DB;
$sql = "SELECT f.id, f.criterionid, f.levelid, f.remark, f.remarkformat
Expand All @@ -250,6 +283,7 @@ public function get_grading($raterid, $itemid) {
}
// TODO: remarks
}
$rs->close();
return $grading;
}

Expand Down
65 changes: 57 additions & 8 deletions grade/grading/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,26 @@ public function set_area($area) {
public function get_component_title() {

$this->ensure_isset(array('context', 'component'));
list($context, $course, $cm) = get_context_info_array($this->get_context()->id);

if (!empty($cm->name)) {
$title = $cm->name;
if ($this->get_context()->contextlevel == CONTEXT_SYSTEM) {
if ($this->get_component() == 'core_grading') {
$title = ''; // we are in the bank UI
} else {
throw new coding_exception('Unsupported component at the system context');
}

} else if ($this->get_context()->contextlevel >= CONTEXT_COURSE) {
list($context, $course, $cm) = get_context_info_array($this->get_context()->id);

if (!empty($cm->name)) {
$title = $cm->name;
} else {
debugging('Gradable areas are currently supported at the course module level only', DEBUG_DEVELOPER);
$title = $this->get_component();
}

} else {
debugging('Gradable areas are currently supported at the course module level only', DEBUG_DEVELOPER);
$title = $this->get_component();
throw new coding_exception('Unsupported gradable area context level');
}

return $title;
Expand All @@ -174,10 +187,22 @@ public function get_component_title() {
*/
public function get_area_title() {

$this->ensure_isset(array('context', 'component', 'area'));
$areas = $this->get_available_areas();
if ($this->get_context()->contextlevel == CONTEXT_SYSTEM) {
return '';

} else if ($this->get_context()->contextlevel >= CONTEXT_COURSE) {
$this->ensure_isset(array('context', 'component', 'area'));
$areas = $this->get_available_areas();
if (array_key_exists($this->get_area(), $areas)) {
return $areas[$this->get_area()];
} else {
debugging('Unknown area!');
return '???';
}

return $areas[$this->get_area()];
} else {
throw new coding_exception('Unsupported context level');
}
}

/**
Expand Down Expand Up @@ -240,6 +265,7 @@ public function get_available_areas() {
// require_once($CFG->dirroot.'/mod/assignment/lib.php');
// return assignment_gradable_area_list();

// todo - what to return for bank areas in the system context
// todo - hardcoded list for now
return array('submission' => 'Submissions');
}
Expand Down Expand Up @@ -465,6 +491,29 @@ public function get_management_url(moodle_url $returnurl = null) {
return new moodle_url('/grade/grading/manage.php', $params);
}

/**
* Creates a new shared area to hold a grading form template
*
* Shared area are implemented as virtual gradable areas at the system level context
* with the component set to core_grading and unique random area name.
*
* @param string $method the name of the plugin we create the area for
* @return int the new area id
*/
public function create_shared_area($method) {
global $DB;

// generate some unique random name for the new area
$name = $method . '_' . sha1(rand().uniqid($method, true));
// create new area record
$area = array(
'contextid' => get_system_context()->id,
'component' => 'core_grading',
'areaname' => $name,
'activemethod' => $method);
return $DB->insert_record('grading_areas', $area);
}

////////////////////////////////////////////////////////////////////////////

/**
Expand Down
72 changes: 64 additions & 8 deletions grade/grading/manage.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@
require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->dirroot.'/grade/grading/lib.php');

// identify gradable area by its id
$areaid = optional_param('areaid', null, PARAM_INT);
// alternatively the context, component and areaname must be provided
$contextid = optional_param('contextid', null, PARAM_INT);
$component = optional_param('component', null, PARAM_COMPONENT);
$area = optional_param('area', null, PARAM_AREA);
// keep the caller's URL so that we know where to send the user finally
$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
// active method selector
$setmethod = optional_param('setmethod', null, PARAM_PLUGIN);
// publish the given form definition as a new template in the forms bank
$shareform = optional_param('shareform', null, PARAM_INT);
// consider the required action as confirmed
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// a message to display, typically a previous action's result
$message = optional_param('message', null, PARAM_NOTAGS);

if (!is_null($areaid)) {
// get manager by id
Expand All @@ -47,17 +57,30 @@
// currently active method
$method = $manager->get_active_method();

list($context, $course, $cm) = get_context_info_array($manager->get_context()->id);
if ($manager->get_context()->contextlevel == CONTEXT_SYSTEM) {
// this is a shared area in the forms bank, redirect the user
$params = array('areaid' =>$areaid);
if (!is_null($returnurl)) {
$params['returnurl'] = $returnurl;
}
redirect(new moodle_url('/grade/grading/bank.php', $params));

} else if ($manager->get_context()->contextlevel >= CONTEXT_COURSE) {
list($context, $course, $cm) = get_context_info_array($manager->get_context()->id);

if (is_null($returnurl)) {
$returnurl = new moodle_url('/course/view.php', array('id' => $course->id));
} else {
$returnurl = new moodle_url($returnurl);
}

require_login($course, true, $cm);
require_capability('moodle/grade:managegradingforms', $context);

if (is_null($returnurl)) {
$returnurl = new moodle_url('/course/view.php', array('id' => $course->id));
} else {
$returnurl = new moodle_url($returnurl);
throw new coding_exception('Unsupported gradable area context level');
}

require_login($course, true, $cm);
require_capability('moodle/grade:managegradingforms', $context);

$PAGE->set_url($manager->get_management_url($returnurl));
navigation_node::override_active_url($manager->get_management_url());
$PAGE->set_title(get_string('gradingmanagement', 'core_grading'));
Expand All @@ -75,7 +98,35 @@
redirect($PAGE->url);
}

// publish the form as a template
if (!empty($shareform)) {
require_capability('moodle/grade:sharegradingforms', get_system_context());
$controller = $manager->get_controller($method);
$definition = $controller->get_definition();
if (!$confirmed) {
// let the user confirm they understand what they are doing (haha ;-)
echo $output->header();
echo $output->confirm(get_string('manageactionshareconfirm', 'core_grading', s($definition->name)),
new moodle_url($PAGE->url, array('shareform' => $shareform, 'confirmed' => 1)),
$PAGE->url);
echo $output->footer();
die();
} else {
require_sesskey();
$newareaid = $manager->create_shared_area($method);
$targetarea = get_grading_manager($newareaid);
$targetcontroller = $targetarea->get_controller($method);
$targetcontroller->update_definition($controller->get_definition_copy($targetcontroller));
redirect(new moodle_url($PAGE->url, array('message' => get_string('manageactionsharedone', 'core_grading'))));
}
}

echo $output->header();

if (!empty($message)) {
echo $output->management_message($message);
}

echo $output->heading(get_string('gradingmanagementtitle', 'core_grading', array(
'component' => $manager->get_component_title(), 'area' => $manager->get_area_title())));

Expand All @@ -88,10 +139,15 @@
// display relevant actions
echo $output->container_start('actions');
if ($controller->is_form_defined()) {
$definition = $controller->get_definition();
echo $output->management_action_icon($controller->get_editor_url($returnurl),
get_string('manageactionedit', 'core_grading'), 'b/document-properties');
get_string('manageactionedit', 'core_grading'), 'b/document-edit');
echo $output->management_action_icon($PAGE->url,
get_string('manageactiondelete', 'core_grading'), 'b/edit-delete');
if (has_capability('moodle/grade:sharegradingforms', get_system_context())) {
echo $output->management_action_icon(new moodle_url($PAGE->url, array('shareform' => $definition->id)),
get_string('manageactionshare', 'core_grading'), 'b/bookmark-new');
}
} else {
echo $output->management_action_icon($controller->get_editor_url($returnurl),
get_string('manageactionnew', 'core_grading'), 'b/document-new');
Expand Down
12 changes: 12 additions & 0 deletions grade/grading/renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ public function management_action_icon(moodle_url $url, $text, $icon) {
return html_writer::link($url, $img . $txt, array('class' => 'action'));
}

/**
* Renders a message for the user, typically as an action result
*
* @param string $message
* @return string
*/
public function management_message($message) {
$this->page->requires->strings_for_js(array('clicktoclose'), 'core_grading');
$this->page->requires->yui_module('moodle-core_grading-manage', 'M.core_grading.init_manage');
return $this->output->box(format_string($message).html_writer::tag('span', ''), 'message', 'actionresultmessagebox');
}

/**
* Renders the common information about the form definition
*
Expand Down
48 changes: 48 additions & 0 deletions grade/grading/yui/manage/manage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* YUI module for advanced grading methods - the manage page
*
* @author David Mudrak <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
YUI.add('moodle-core_grading-manage', function(Y) {

var MANAGE = function() {
MANAGE.superclass.constructor.apply(this, arguments);
}

Y.extend(MANAGE, Y.Base, {

initializer : function(config) {
this.setup_messagebox();
},

setup_messagebox : function() {
Y.one('#actionresultmessagebox span').setContent(M.util.get_string('clicktoclose', 'core_grading'));
Y.one('#actionresultmessagebox').on('click', function(e) {
e.halt();
var box = e.currentTarget;
var anim = new Y.Anim({
node: box,
from: { opacity: 1 },
to: { opacity: 0 },
});
anim.run();
anim.on('end', function() {
var box = this.get('node'); // this === anim
box.remove(true);
});
});
}

}, {
NAME : 'grading_manage_page',
ATTRS : { }
});

M.core_grading = M.core_grading || {};

M.core_grading.init_manage = function(config) {
return new MANAGE(config);
}

}, '@VERSION@', { requires:['base', 'anim'] });
8 changes: 6 additions & 2 deletions lang/en/grading.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
$string['activemethodinfo'] = '\'{$a->method}\' is selected as the active grading method for the \'{$a->area}\' area';
$string['activemethodinfonone'] = 'There is no advanced grading method selected for the \'{$a->area}\' area. Simple direct grading will be used.';
$string['changeactivemethod'] = 'Change active grading method to';
$string['clicktoclose'] = 'click to close';
$string['exc_gradingformelement'] = 'Unable to instantiate grading form element';
$string['formnotavailable'] = 'Advanced grading method was selected to use but the grading form is not available yet. You may need to define it first via a link in the Settings block.';
$string['gradingmanagement'] = 'Advanced grading';
Expand All @@ -37,10 +38,13 @@
$string['gradingmethod_help'] = 'Choose the advanced grading method that should be used for calculating grades in the given context.
To disable advance grading and switch back to the default grading mechanism, choose \'Simple direct grading\'.';
$string['gradingmethods'] = 'Grading methods';
$string['gradingmethodnone'] = 'Simple direct grading';
$string['manageactionclone'] = 'Create new grading form from template';
$string['gradingmethods'] = 'Grading methods';
$string['manageactionclone'] = 'Create new grading form from a template';
$string['manageactiondelete'] = 'Remove the currently defined form';
$string['manageactionedit'] = 'Edit the current form definition';
$string['manageactionnew'] = 'Define new grading form from scratch';
$string['manageactionshare'] = 'Publish the form as a new template';
$string['manageactionshareconfirm'] = 'You are going to save a copy of the grading form \'{$a}\' as a new public template. Other users at your site will be able to create new grading forms in their activities from that template. Note that users are able to reuse their own grading forms in other activities even if the forms were not saved as template.';
$string['manageactionsharedone'] = 'The form was successfully saved as a template';
$string['noitemid'] = 'Grading not possible. The graded item does not exist.';
Binary file added pix/b/bookmark-new.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pix/b/document-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion theme/standard/style/grade.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ td.grade div.overridden {background-color: #DDDDDD;}
#page-grade-grading-manage .actions {text-align:center;}
#page-grade-grading-manage .action {display:inline-block;width: 150px;background-color:#EEE;border:2px solid #CCC;
margin:0.5em;padding:0.5em;text-align:center;-moz-border-radius:5px}
#page-grade-grading-manage .action:hover {text-decoration:none;background-color:#F6F6F6;
#page-grade-grading-manage .action:hover {text-decoration:none;background-color:#F6F6F6;}
#page-grade-grading-manage #actionresultmessagebox {background-color:#D2EBFF;width:60%;margin:1em auto 1em auto;text-align:center;
padding:0.5em;border:2px solid #CCC;text-align:center;-moz-border-radius:5px;position:relative}
#page-grade-grading-manage #actionresultmessagebox span {position:absolute;right:0px;top:-1.2em;color:#666;font-size:80%}

0 comments on commit fde3380

Please sign in to comment.