MDL-29794 It is now possible to re-use a form without sharing it as a template

The patch also improves displaying tags-like status information next to
the grading form titles.
This commit is contained in:
David Mudrak 2011-11-02 21:57:24 +01:00
parent ce7f5c8d3b
commit 967d346f72
6 changed files with 108 additions and 24 deletions

View File

@ -125,6 +125,36 @@ abstract class gradingform_controller {
return ($this->is_form_defined() && $this->definition->status == self::DEFINITION_STATUS_READY);
}
/**
* Is the grading form saved as a shared public template?
*
* @return boolean
*/
public function is_shared_template() {
return ($this->get_context()->id == context_system::instance()->id
and $this->get_component() == 'core_grading');
}
/**
* Is the grading form owned by the given user?
*
* The form owner is the user who created this instance of the form.
*
* @param int $userid the user id to check, defaults to the current user
* @return boolean|null null if the form not defined yet, boolean otherwise
*/
public function is_own_form($userid = null) {
global $USER;
if (!$this->is_form_defined()) {
return null;
}
if (is_null($userid)) {
$userid = $USER->id;
}
return ($this->definition->usercreated == $userid);
}
/**
* Returns a message why this form is unavailable. Maybe overriden by plugins to give more details.
* @see is_form_available()

View File

@ -229,9 +229,9 @@ if (!empty($method)) {
// display the grading form preview
if ($controller->is_form_defined()) {
if ($definition->status == gradingform_controller::DEFINITION_STATUS_READY) {
$tag = html_writer::tag('span', get_string('statusready', 'core_grading'), array('class' => 'status-ready'));
$tag = html_writer::tag('span', get_string('statusready', 'core_grading'), array('class' => 'status ready'));
} else {
$tag = html_writer::tag('span', get_string('statusdraft', 'core_grading'), array('class' => 'status-draft'));
$tag = html_writer::tag('span', get_string('statusdraft', 'core_grading'), array('class' => 'status draft'));
}
echo $output->heading(s($definition->name) . ' ' . $tag, 3, 'definition-name');
echo $output->box($controller->get_formatted_description());

View File

@ -71,6 +71,13 @@ if ($pick) {
$sourceid = $DB->get_field('grading_definitions', 'areaid', array('id' => $pick), MUST_EXIST);
$sourcemanager = get_grading_manager($sourceid);
$sourcecontroller = $sourcemanager->get_controller($method);
if (!$sourcecontroller->is_shared_template() and !$sourcecontroller->is_own_form()) {
// note that we don't actually check whether the user has still the capability
// moodle/grade:managegradingforms in the source area. so when users loose
// their teacher role in a course, they can't access the course but they can
// still copy the forms they have created there.
throw new moodle_exception('attempt_to_pick_others_form', 'core_grading');
}
if (!$sourcecontroller->is_form_defined()) {
throw new moodle_exception('form_definition_mismatch', 'core_grading');
}
@ -99,6 +106,9 @@ if ($remove) {
$sourceid = $DB->get_field('grading_definitions', 'areaid', array('id' => $remove), MUST_EXIST);
$sourcemanager = get_grading_manager($sourceid);
$sourcecontroller = $sourcemanager->get_controller($method);
if (!$sourcecontroller->is_shared_template()) {
throw new moodle_exception('attempt_to_delete_nontemplate', 'core_grading');
}
if (!$sourcecontroller->is_form_defined()) {
throw new moodle_exception('form_definition_mismatch', 'core_grading');
}
@ -126,12 +136,11 @@ if ($remove) {
$searchform = new grading_search_template_form($PAGE->url, null, 'GET', '', array('class' => 'templatesearchform'));
if ($searchdata = $searchform->get_data()) {
$needle = $searchdata->needle;
$searchform->set_data(array(
'needle' => $needle,
));
$tokens = grading_manager::tokenize($searchdata->needle);
$includeownforms = (!empty($searchdata->mode));
} else {
$needle = '';
$tokens = array();
$includeownforms = false;
}
// construct the SQL to find all matching templates
@ -142,13 +151,23 @@ $sql = "SELECT DISTINCT gd.id, gd.areaid, gd.name, gd.description, gd.descriptio
// join method-specific tables from the plugin scope
$sql .= $targetcontrollerclass::sql_search_from_tables('gd.id');
$sql .= " WHERE gd.method = ?
AND ga.contextid = ?
AND ga.component = 'core_grading'";
$sql .= " WHERE gd.method = ?";
$params = array($method, get_system_context()->id);
$params = array($method);
if (!$includeownforms) {
// search for public templates only
$sql .= " AND ga.contextid = ? AND ga.component = 'core_grading'";
$params[] = get_system_context()->id;
} else {
// search both templates and own forms in other areas
$sql .= " AND ((ga.contextid = ? AND ga.component = 'core_grading')
OR (gd.usercreated = ? AND gd.status = ?))";
$params = array_merge($params, array(get_system_context()->id, $USER->id,
gradingform_controller::DEFINITION_STATUS_READY));
}
$tokens = grading_manager::tokenize($needle);
if ($tokens) {
$subsql = array();
@ -185,18 +204,38 @@ $found = 0;
foreach ($rs as $template) {
$found++;
$out = '';
$out .= $output->heading(s($template->name), 2, 'template-name');
$manager = get_grading_manager($template->areaid);
$controller = $manager->get_controller($method);
if ($controller->is_shared_template()) {
$templatetag = html_writer::tag('span', get_string('templatetypeshared', 'core_grading'),
array('class' => 'type shared'));
$templatesrc = '';
} else if ($controller->is_own_form()) {
$templatetag = html_writer::tag('span', get_string('templatetypeown', 'core_grading'),
array('class' => 'type ownform'));
$templatesrc = get_string('templatesource', 'core_grading', array(
'component' => $manager->get_component_title(),
'area' => $manager->get_area_title()));
} else {
throw new coding_exception('Something is wrong, the displayed form must be either template or own form');
}
$out .= $output->heading(s($template->name).' '.$templatetag, 2, 'template-name');
$out .= $output->container($templatesrc, 'template-source');
$out .= $output->box($controller->render_preview($PAGE), 'template-preview');
$actions = array($output->pick_action_icon(new moodle_url($PAGE->url, array('pick' => $template->id)),
get_string('templatepick', 'core_grading'), 'i/tick_green_big', 'pick'));
$actions = array();
if ($controller->is_shared_template()) {
$actions[] = $output->pick_action_icon(new moodle_url($PAGE->url, array('pick' => $template->id)),
get_string('templatepick', 'core_grading'), 'i/tick_green_big', 'pick template');
if ($canmanage or ($canshare and ($template->usercreated == $USER->id))) {
//$actions[] = $output->pick_action_icon(new moodle_url($PAGE->url, array('edit' => $template->id)),
// get_string('templateedit', 'core_grading'), 'i/edit', 'edit');
$actions[] = $output->pick_action_icon(new moodle_url($PAGE->url, array('remove' => $template->id)),
get_string('templatedelete', 'core_grading'), 't/delete', 'remove');
}
} else if ($controller->is_own_form()) {
$actions[] = $output->pick_action_icon(new moodle_url($PAGE->url, array('pick' => $template->id)),
get_string('templatepickownform', 'core_grading'), 'i/tick_green_big', 'pick ownform');
}
$out .= $output->box(join(' ', $actions), 'template-actions');
$out .= $output->box($controller->get_formatted_description(), 'template-description');

View File

@ -38,7 +38,10 @@ class grading_search_template_form extends moodleform {
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('header', 'searchheader', get_string('searchtemplate', 'core_grading'));
$mform->addHelpButton('searchheader', 'searchtemplate', 'core_grading');
$mform->addGroup(array(
$mform->createElement('checkbox', 'mode', '', get_string('searchownforms', 'core_grading')),
$mform->createElement('text', 'needle', '', array('size' => 30)),
$mform->createElement('submit', 'submitbutton', get_string('search')),
), 'buttonar', '', array(' '), false);

View File

@ -58,6 +58,11 @@ $string['manageactionshareconfirm'] = 'You are going to save a copy of the gradi
$string['manageactionsharedone'] = 'The form was successfully saved as a template';
$string['noitemid'] = 'Grading not possible. The graded item does not exist.';
$string['nosharedformfound'] = 'No template found';
$string['searchtemplate'] = 'Grading forms search';
$string['searchtemplate_help'] = 'You can search for a grading form and use it as a template for the new grading form here. Simply type words that should appear somewhere in the form name, its description or the form body itself. To search for a phrase, wrap the whole query in double quotes.
By default, only the grading forms that have been saved as shared templates are included in the search results. You can also include all your own grading forms in the search results. This way, you can simply re-use your grading forms without sharing them. Only forms marked as \'Ready for usage\' can be re-used this way.';
$string['searchownforms'] = 'include my own forms';
$string['statusdraft'] = 'Draft';
$string['statusready'] = 'Ready for usage';
$string['templatedelete'] = 'Delete';
@ -65,3 +70,7 @@ $string['templatedeleteconfirm'] = 'You are going to delete the shared template
$string['templateedit'] = 'Edit';
$string['templatepick'] = 'Use this template';
$string['templatepickconfirm'] = 'Do you want to use the grading form \'{$a->formname}\' as a template for the new grading form in \'{$a->component} ({$a->area})\'?';
$string['templatepickownform'] = 'Use this form as a template';
$string['templatetypeown'] = 'Own form';
$string['templatetypeshared'] = 'Shared template';
$string['templatesource'] = 'Location: {$a->component} ({$a->area})';

View File

@ -45,12 +45,15 @@ td.grade div.overridden {background-color: #DDDDDD;}
#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%}
#page-grade-grading-manage .definition-name span {padding:0.25em;font-weight:bold;text-transform:uppercase;}
#page-grade-grading-manage .definition-name span.status-ready {background-color:#e7f1c3;border:2px solid #AAEEAA;}
#page-grade-grading-manage .definition-name span.status-draft {background-color:#f3f2aa;border:2px solid #EEEE22;}
#page-grade-grading-manage .definition-name .status {font-weight:normal;text-transform:uppercase;font-size:60%;padding:0.25em;border:1px solid #EEE;-moz-border-radius:5px;}
#page-grade-grading-manage .definition-name .status.ready {background-color:#e7f1c3;border-color:#AAEEAA;}
#page-grade-grading-manage .definition-name .status.draft {background-color:#f3f2aa;border-color:#EEEE22;}
#page-grade-grading-manage .definition-preview {width:50%;margin:1em auto;border:1px solid #EEE; padding: 1em;}
#page-grade-grading-pick .templatesearchform {text-align:center;margin:0px auto;}
#page-grade-grading-pick .templatesearchform {}
#page-grade-grading-pick .template-name {clear: both; padding:3px; background-color: #F6F6F6;}
#page-grade-grading-pick .template-name .type {font-weight:normal;text-transform:uppercase;font-size:60%;padding:0.25em;border:1px solid #EEE;-moz-border-radius:5px;}
#page-grade-grading-pick .template-name .type.shared {background-color:#e7f1c3;border-color:#AAEEAA}
#page-grade-grading-pick .template-name .type.ownform {background-color:#d2ebff;border-color:#AACCEE}
#page-grade-grading-pick .template-description {margin-bottom: 1em; padding: 0px 2em 0px 0px; margin-right:51%;}
#page-grade-grading-pick .template-preview {width:50%; float:right; border:1px solid #EEE; padding: 1em; margin-bottom: 1em;}
#page-grade-grading-pick .template-actions {margin-bottom: 1em; padding: 0px 2em 0px 0px; margin-right:51%;}