From 5383ba0d437b26ff3f2ba749de7fa3ef5523706c Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Wed, 22 Apr 2009 08:36:22 +0000 Subject: [PATCH] MDL-18083 MDL-14961 MDL-15680 MDL-16913 New Edit Categories and Items interface with heaps of improvements. Replaces the original page. Also added a help string for the "synchronise legacy grades" button. --- grade/edit/tree/index.php | 352 ++++++++++++++++++++++++-------------- 1 file changed, 226 insertions(+), 126 deletions(-) diff --git a/grade/edit/tree/index.php b/grade/edit/tree/index.php index 3d3e5f3c2d1..2285c6baba9 100644 --- a/grade/edit/tree/index.php +++ b/grade/edit/tree/index.php @@ -26,14 +26,19 @@ require_once '../../../config.php'; require_once $CFG->dirroot.'/grade/lib.php'; require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences +require_once $CFG->dirroot.'/grade/edit/tree/lib.php'; -$courseid = required_param('id', PARAM_INT); -$action = optional_param('action', 0, PARAM_ALPHA); -$eid = optional_param('eid', 0, PARAM_ALPHANUM); +require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_json', 'yui_connection', 'yui_dragdrop', 'yui_treeview', 'yui_element', + $CFG->wwwroot.'/grade/edit/tree/functions.js')); +$courseid = required_param('id', PARAM_INT); +$action = optional_param('action', 0, PARAM_ALPHA); +$eid = optional_param('eid', 0, PARAM_ALPHANUM); +$category = optional_param('category', null, PARAM_INT); +$aggregationtype = optional_param('aggregationtype', null, PARAM_INT); +$showadvanced = optional_param('showadvanced', -1, PARAM_BOOL); // sticky editting mode /// Make sure they can even access this course - if (!$course = get_record('course', 'id', $courseid)) { print_error('nocourseid'); } @@ -46,6 +51,52 @@ require_capability('moodle/grade:manage', $context); $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); $returnurl = $gpr->get_return_url(null); +/// Build editing on/off buttons +if (!isset($USER->gradeediting)) { + $USER->gradeediting = array(); +} + +$current_view = ''; + +if (has_capability('moodle/grade:manage', $context)) { + if (!isset($USER->gradeediting[$course->id])) { + $USER->gradeediting[$course->id] = 0; + } + + if (($showadvanced == 1) and confirm_sesskey()) { + $USER->gradeediting[$course->id] = 1; + } else if (($showadvanced == 0) and confirm_sesskey()) { + $USER->gradeediting[$course->id] = 0; + } + + // page params for the turn editting on + $options = $gpr->get_options(); + $options['sesskey'] = sesskey(); + + if ($USER->gradeediting[$course->id]) { + $options['showadvanced'] = 0; + $current_view = 'fullview'; + } else { + $options['showadvanced'] = 1; + $current_view = 'simpleview'; + } + +} else { + $USER->gradeediting[$course->id] = 0; + $buttons = ''; +} + +// Change category aggregation if requested +if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) { + if (!$grade_category = grade_category::fetch(array('id'=>$category, 'courseid'=>$courseid))) { + error('Incorrect category id!'); + } + $data->aggregation = $aggregationtype; + grade_category::set_properties($grade_category, $data); + $grade_category->update(); + grade_regrade_final_grades($courseid); +} + //first make sure we have proper final grades - we need it for locking changes grade_regrade_final_grades($courseid); @@ -59,7 +110,7 @@ if (empty($eid)) { } else { if (!$element = $gtree->locate_element($eid)) { - error('Incorrect element id!', $returnurl); + print_error('invalidelementid', '', $returnurl); } $object = $element['object']; } @@ -74,10 +125,12 @@ $strcategoriesanditems = get_string('categoriesanditems', 'grades'); $navigation = grade_build_nav(__FILE__, $strcategoriesanditems, array('courseid' => $courseid)); $moving = false; +$grade_edit_tree = new grade_edit_tree($gtree, $moving, $gpr); + switch ($action) { case 'delete': - if ($eid) { - if (!element_deletable($element)) { + if ($eid && confirm_sesskey()) { + if (!$grade_edit_tree->element_deletable($element)) { // no deleting of external activities - they would be recreated anyway! // exception is activity without grading or misconfigured activities break; @@ -89,7 +142,7 @@ switch ($action) { redirect($returnurl); } else { - print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course)); + print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, null, navmenu($course)); $strdeletecheckfull = get_string('deletecheck', '', $object->get_name()); $optionsyes = array('eid'=>$eid, 'confirm'=>1, 'sesskey'=>sesskey(), 'id'=>$course->id, 'action'=>'delete'); $optionsno = array('id'=>$course->id); @@ -111,14 +164,22 @@ switch ($action) { case 'move': if ($eid and confirm_sesskey()) { $moveafter = required_param('moveafter', PARAM_ALPHANUM); + $first = optional_param('first', false, PARAM_BOOL); // If First is set to 1, it means the target is the first child of the category $moveafter + if(!$after_el = $gtree->locate_element($moveafter)) { - error('Incorect element id in moveafter', $returnurl); + print_error('invalidelementid', '', $returnurl); } + $after = $after_el['object']; - $parent = $after->get_parent_category(); $sortorder = $after->get_sortorder(); - $object->set_parent($parent->id); + if (!$first) { + $parent = $after->get_parent_category(); + $object->set_parent($parent->id); + } else { + $object->set_parent($after->id); + } + $object->move_after_sortorder($sortorder); redirect($returnurl); @@ -127,7 +188,8 @@ switch ($action) { case 'moveselect': if ($eid and confirm_sesskey()) { - $moving = $eid; + $grade_edit_tree->moving = $eid; + $moving=true; } break; @@ -135,143 +197,181 @@ switch ($action) { break; } -print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course)); +// Hide advanced columns if moving +if ($grade_edit_tree->moving) { + $original_gradeediting = $USER->gradeediting[$course->id]; + $USER->gradeediting[$course->id] = 0; +} -/// Print the plugin selector at the top -print_grade_plugin_selector($courseid, 'edit', 'tree'); +$CFG->stylesheets[] = $CFG->wwwroot.'/grade/edit/tree/tree.css'; -print_heading(get_string('categoriesedit', 'grades')); +$current_view_str = ''; +if ($current_view != '') { + if ($current_view == 'simpleview') { + $current_view_str = get_string('simpleview', 'grades'); + } elseif ($current_view == 'fullview') { + $current_view_str = get_string('fullview', 'grades'); + } +} +print_grade_page_head($courseid, 'edittree', $current_view, get_string('categoriesedit', 'grades') . ': ' . $current_view_str); +$form_key = optional_param('sesskey', null, PARAM_ALPHANUM); + +if ($form_key && $data = data_submitted()) { + // Perform bulk actions first + if (!empty($data->bulkmove) && confirm_sesskey()) { + $elements = array(); + + foreach ($data as $key => $value) { + if (preg_match('/select_(i[0-9]*)/', $key, $matches)) { + $elements[] = $matches[1]; + } + } + + $grade_edit_tree->move_elements($elements, $returnurl); + } + + // Category and item field updates + foreach ($data as $key => $value) { + // Grade category text inputs + if (preg_match('/(aggregation|droplow|keephigh)_([0-9]*)/', $key, $matches) && confirm_sesskey()) { + $value = required_param($matches[0], PARAM_INT); + $param = $matches[1]; + $a->id = $matches[2]; + + $grade_category = grade_category::fetch(array('id'=>$a->id, 'courseid'=>$courseid)); + $grade_category->$param = $value; + + $grade_category->update(); + grade_regrade_final_grades($courseid); + + // Grade item text inputs + } elseif (preg_match('/(grademax|aggregationcoef|multfactor|plusfactor)_([0-9]*)/', $key, $matches) && confirm_sesskey()) { + $defaults = array('grademax' => 100, 'aggregationcoef' => 1, 'multfactor' => 1, 'plusfactor' => 0); + + if (is_string($_POST[$matches[0]]) && strlen($_POST[$matches[0]]) < 1) { + $_POST[$matches[0]] = null; + } + $value = optional_param($matches[0], $defaults[$matches[1]], PARAM_NUMBER); + + $param = $matches[1]; + $a->id = $matches[2]; + $grade_item = grade_item::fetch(array('id'=>$a->id, 'courseid'=>$courseid)); + $grade_item->$param = $value; + + $grade_item->update(); + grade_regrade_final_grades($courseid); + + // Grade item checkbox inputs + } elseif (preg_match('/extracredit_original_([0-9]*)/', $key, $matches) && confirm_sesskey()) { // Sum extra credit checkbox + $extracredit = optional_param("extracredit_{$matches[1]}", null, PARAM_BOOL); + $original_value = required_param($matches[0], PARAM_BOOL); + $a->id = $matches[1]; + $newvalue = null; + if ($original_value == 1 && is_null($extracredit)) { + $newvalue = 0; + } elseif ($original_value == 0 && $extracredit == 1) { + $newvalue = 1; + } else { + continue; + } + + $grade_item = grade_item::fetch(array('id'=>$a->id, 'courseid'=>$courseid)); + $grade_item->aggregationcoef = $newvalue; + + $grade_item->update(); + grade_regrade_final_grades($courseid); + + // Grade category checkbox inputs + } elseif (preg_match('/aggregate(onlygraded|subcats|outcomes)_original_([0-9]*)/', $key, $matches) && confirm_sesskey()) { + $setting = optional_param('aggregate'.$matches[1].'_'.$matches[2], null, PARAM_BOOL); + $original_value = required_param($matches[0], PARAM_BOOL); + $a->id = $matches[2]; + + $newvalue = null; + if ($original_value == 1 && is_null($setting)) { + $newvalue = 0; + } elseif ($original_value == 0 && $setting == 1) { + $newvalue = 1; + } else { + continue; + } + + $grade_category = grade_category::fetch(array('id'=>$a->id, 'courseid'=>$courseid)); + $grade_category->{'aggregate'.$matches[1]} = $newvalue; + + $grade_category->update(); + grade_regrade_final_grades($courseid); + } + } +} + +// Print Table of categories and items print_box_start('gradetreebox generalbox'); -echo ''; + +echo '
'; +echo '
'; +echo ''; + +// Build up an array of categories for move drop-down (by reference) +$categories = array(); +echo $grade_edit_tree->build_html_tree($gtree->top_element, true, array(), $categories); + +echo '
'; +if (!$moving) { + echo ''; +} + +if (!$moving) { + echo '

'; + echo ''; + echo get_string('moveselectedto', 'grades') . ' : '; + echo choose_from_menu($categories, 'moveafter', '', 'choose', + 'document.getElementById(\'bulkmoveinput\').value=1;document.getElementById(\'gradetreeform\').submit()', 0, true); + echo '
+ +
+ '; +} + +echo '
'; + +echo '
'; + print_box_end(); +// Print action buttons echo '
'; + if ($moving) { print_single_button('index.php', array('id'=>$course->id), get_string('cancel'), 'get'); } else { print_single_button('category.php', array('courseid'=>$course->id), get_string('addcategory', 'grades'), 'get'); print_single_button('item.php', array('courseid'=>$course->id), get_string('additem', 'grades'), 'get'); + if (!empty($CFG->enableoutcomes)) { print_single_button('outcomeitem.php', array('courseid'=>$course->id), get_string('addoutcomeitem', 'grades'), 'get'); } + //print_single_button('index.php', array('id'=>$course->id, 'action'=>'autosort'), get_string('autosort', 'grades'), 'get'); echo "

"; print_single_button('index.php', array('id'=>$course->id, 'action'=>'synclegacy'), get_string('synclegacygrades', 'grades'), 'get'); helpbutton('synclegacygrades', get_string('synclegacygrades', 'grades'), 'grade'); } + echo '
'; + print_footer($course); + +// Restore original show/hide preference if moving +if ($moving) { + $USER->gradeediting[$course->id] = $original_gradeediting; +} die; -/** - * TODO document - */ -function print_grade_tree(&$gtree, $element, $moving, &$gpr, $switch, $switchedlast=false) { - global $CFG, $COURSE; - -/// fetch needed strings - $strmove = get_string('move'); - $strmovehere = get_string('movehere'); - $strdelete = get_string('delete'); - - $object = $element['object']; - $eid = $element['eid']; - - $header = $gtree->get_element_header($element, true, true, true); - - if ($object->is_hidden()) { - $header = ''.$header.''; - } - -/// prepare actions - $actions = $gtree->get_edit_icon($element, $gpr); - $actions .= $gtree->get_calculation_icon($element, $gpr); - - if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) { - if (element_deletable($element)) { - $actions .= ''
-                     . $strdelete.''; - } - $actions .= ''
-                 . $strmove.''; - } - - $actions .= $gtree->get_hiding_icon($element, $gpr); - $actions .= $gtree->get_locking_icon($element, $gpr); - -/// prepare move target if needed - $last = ''; - $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem'); - $moveto = ''; - if ($moving) { - $actions = ''; // no action icons when moving - $moveto = '
  • '
-                . $strmovehere.'
  • '; - } - -/// print the list items now - if ($moving == $eid) { - // do not diplay children - echo '
  • '.$header.'('.get_string('move').')
  • '; - - } else if ($element['type'] != 'category') { - if ($catcourseitem and $switch) { - if ($switchedlast) { - echo '
  • '.$header.$actions.'
  • '; - } else { - echo $moveto; - } - } else { - echo '
  • '.$header.$actions.'
  • '.$moveto; - } - - } else { - echo '
  • '.$header.$actions; - echo '
  • '; - if ($element['depth'] > 1) { - echo $moveto; // can not move after the top category - } - } -} - -function element_deletable($element) { - global $COURSE; - - if ($element['type'] != 'item') { - return true; - } - - $grade_item = $element['object']; - - if ($grade_item->itemtype != 'mod' or $grade_item->is_outcome_item() or $grade_item->gradetype == GRADE_TYPE_NONE) { - return true; - } - - $modinfo = get_fast_modinfo($COURSE); - if (!isset($modinfo->instances[$grade_item->itemmodule][$grade_item->iteminstance])) { - // module does not exist - return true; - } - - return false; -} - ?>