|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00026 require_once '../../../config.php'; 00027 require_once $CFG->dirroot.'/grade/lib.php'; 00028 require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences 00029 require_once $CFG->dirroot.'/grade/edit/tree/lib.php'; 00030 00031 $courseid = required_param('id', PARAM_INT); 00032 $action = optional_param('action', 0, PARAM_ALPHA); 00033 $eid = optional_param('eid', 0, PARAM_ALPHANUM); 00034 $category = optional_param('category', null, PARAM_INT); 00035 $aggregationtype = optional_param('aggregationtype', null, PARAM_INT); 00036 $showadvanced = optional_param('showadvanced', -1, PARAM_BOOL); // sticky editing mode 00037 00038 $url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid)); 00039 if($showadvanced!=-1) { 00040 $url->param("showadvanced",$showadvanced); 00041 } 00042 $PAGE->set_url($url); 00043 $PAGE->set_pagelayout('admin'); 00044 00046 if (!$course = $DB->get_record('course', array('id' => $courseid))) { 00047 print_error('nocourseid'); 00048 } 00049 00050 require_login($course); 00051 $context = get_context_instance(CONTEXT_COURSE, $course->id); 00052 require_capability('moodle/grade:manage', $context); 00053 00054 // todo $PAGE->requires->js_module() should be used here instead 00055 $PAGE->requires->yui2_lib('event'); 00056 $PAGE->requires->yui2_lib('json'); 00057 $PAGE->requires->yui2_lib('connection'); 00058 $PAGE->requires->yui2_lib('dragdrop'); 00059 $PAGE->requires->yui2_lib('element'); 00060 $PAGE->requires->yui2_lib('container'); 00061 $PAGE->requires->yui2_lib('animation'); 00062 $PAGE->requires->js('/grade/edit/tree/functions.js'); 00063 00065 $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); 00066 $returnurl = $gpr->get_return_url(null); 00067 00069 if (!isset($USER->gradeediting)) { 00070 $USER->gradeediting = array(); 00071 } 00072 00073 $current_view = ''; 00074 00075 if (has_capability('moodle/grade:manage', $context)) { 00076 if (!isset($USER->gradeediting[$course->id])) { 00077 $USER->gradeediting[$course->id] = 0; 00078 } 00079 00080 if ($showadvanced == 1) { 00081 $USER->gradeediting[$course->id] = 1; 00082 } else if ($showadvanced == 0) { 00083 $USER->gradeediting[$course->id] = 0; 00084 } 00085 00086 // page params for the turn editing on 00087 $options = $gpr->get_options(); 00088 $options['sesskey'] = sesskey(); 00089 00090 if ($USER->gradeediting[$course->id]) { 00091 $options['showadvanced'] = 0; 00092 $current_view = 'fullview'; 00093 } else { 00094 $options['showadvanced'] = 1; 00095 $current_view = 'simpleview'; 00096 } 00097 00098 } else { 00099 $USER->gradeediting[$course->id] = 0; 00100 $buttons = ''; 00101 } 00102 00103 // Change category aggregation if requested 00104 if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) { 00105 if (!$grade_category = grade_category::fetch(array('id'=>$category, 'courseid'=>$courseid))) { 00106 print_error('invalidcategoryid'); 00107 } 00108 00109 $data = new stdClass(); 00110 $data->aggregation = $aggregationtype; 00111 grade_category::set_properties($grade_category, $data); 00112 $grade_category->update(); 00113 00114 grade_regrade_final_grades($courseid); 00115 } 00116 00117 //first make sure we have proper final grades - we need it for locking changes 00118 grade_regrade_final_grades($courseid); 00119 00120 // get the grading tree object 00121 // note: total must be first for moving to work correctly, if you want it last moving code must be rewritten! 00122 $gtree = new grade_tree($courseid, false, false); 00123 00124 if (empty($eid)) { 00125 $element = null; 00126 $object = null; 00127 00128 } else { 00129 if (!$element = $gtree->locate_element($eid)) { 00130 print_error('invalidelementid', '', $returnurl); 00131 } 00132 $object = $element['object']; 00133 } 00134 00135 $switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition); 00136 00137 $strgrades = get_string('grades'); 00138 $strgraderreport = get_string('graderreport', 'grades'); 00139 $strcategoriesedit = get_string('categoriesedit', 'grades'); 00140 $strcategoriesanditems = get_string('categoriesanditems', 'grades'); 00141 00142 $moving = false; 00143 $movingeid = false; 00144 00145 if ($action == 'moveselect') { 00146 if ($eid and confirm_sesskey()) { 00147 $movingeid = $eid; 00148 $moving=true; 00149 } 00150 } 00151 00152 $grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr); 00153 00154 switch ($action) { 00155 case 'delete': 00156 if ($eid && confirm_sesskey()) { 00157 if (!$grade_edit_tree->element_deletable($element)) { 00158 // no deleting of external activities - they would be recreated anyway! 00159 // exception is activity without grading or misconfigured activities 00160 break; 00161 } 00162 $confirm = optional_param('confirm', 0, PARAM_BOOL); 00163 00164 if ($confirm) { 00165 $object->delete('grade/report/grader/category'); 00166 redirect($returnurl); 00167 00168 } else { 00169 $PAGE->set_title($strgrades . ': ' . $strgraderreport); 00170 $PAGE->set_heading($course->fullname); 00171 echo $OUTPUT->header(); 00172 $strdeletecheckfull = get_string('deletecheck', '', $object->get_name()); 00173 $optionsyes = array('eid'=>$eid, 'confirm'=>1, 'sesskey'=>sesskey(), 'id'=>$course->id, 'action'=>'delete'); 00174 $optionsno = array('id'=>$course->id); 00175 $formcontinue = new single_button(new moodle_url('index.php', $optionsyes), get_string('yes')); 00176 $formcancel = new single_button(new moodle_url('index.php', $optionsno), get_string('no'), 'get'); 00177 echo $OUTPUT->confirm($strdeletecheckfull, $formcontinue, $formcancel); 00178 echo $OUTPUT->footer(); 00179 die; 00180 } 00181 } 00182 break; 00183 00184 case 'autosort': 00185 //TODO: implement autosorting based on order of mods on course page, categories first, manual items last 00186 break; 00187 00188 case 'move': 00189 if ($eid and confirm_sesskey()) { 00190 $moveafter = required_param('moveafter', PARAM_ALPHANUM); 00191 $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 00192 00193 if(!$after_el = $gtree->locate_element($moveafter)) { 00194 print_error('invalidelementid', '', $returnurl); 00195 } 00196 00197 $after = $after_el['object']; 00198 $sortorder = $after->get_sortorder(); 00199 00200 if (!$first) { 00201 $parent = $after->get_parent_category(); 00202 $object->set_parent($parent->id); 00203 } else { 00204 $object->set_parent($after->id); 00205 } 00206 00207 $object->move_after_sortorder($sortorder); 00208 00209 redirect($returnurl); 00210 } 00211 break; 00212 00213 default: 00214 break; 00215 } 00216 00217 // Hide advanced columns if moving 00218 if ($grade_edit_tree->moving) { 00219 $original_gradeediting = $USER->gradeediting[$course->id]; 00220 $USER->gradeediting[$course->id] = 0; 00221 } 00222 00223 $current_view_str = ''; 00224 if ($current_view != '') { 00225 if ($current_view == 'simpleview') { 00226 $current_view_str = get_string('simpleview', 'grades'); 00227 } elseif ($current_view == 'fullview') { 00228 $current_view_str = get_string('fullview', 'grades'); 00229 } 00230 } 00231 00232 //if we go straight to the db to update an element we need to recreate the tree as 00233 // $grade_edit_tree has already been constructed. 00234 //Ideally we could do the updates through $grade_edit_tree to avoid recreating it 00235 $recreatetree = false; 00236 00237 if ($data = data_submitted() and confirm_sesskey()) { 00238 // Perform bulk actions first 00239 if (!empty($data->bulkmove)) { 00240 $elements = array(); 00241 00242 foreach ($data as $key => $value) { 00243 if (preg_match('/select_(i[0-9]*)/', $key, $matches)) { 00244 $elements[] = $matches[1]; 00245 } 00246 } 00247 00248 $grade_edit_tree->move_elements($elements, $returnurl); 00249 } 00250 00251 // Category and item field updates 00252 foreach ($data as $key => $value) { 00253 // Grade category text inputs 00254 if (preg_match('/^(aggregation|droplow|keephigh)_([0-9]+)$/', $key, $matches)) { 00255 $param = $matches[1]; 00256 $aid = $matches[2]; 00257 00258 // Do not allow negative values 00259 $value = clean_param($value, PARAM_INT); 00260 $value = ($value < 0) ? 0 : $value; 00261 00262 $grade_category = grade_category::fetch(array('id'=>$aid, 'courseid'=>$courseid)); 00263 $grade_category->$param = $value; 00264 00265 $grade_category->update(); 00266 grade_regrade_final_grades($courseid); 00267 00268 $recreatetree = true; 00269 00270 // Grade item text inputs 00271 } elseif (preg_match('/^(grademax|aggregationcoef|multfactor|plusfactor)_([0-9]+)$/', $key, $matches)) { 00272 $param = $matches[1]; 00273 $aid = $matches[2]; 00274 00275 $value = unformat_float($value); 00276 $value = clean_param($value, PARAM_NUMBER); 00277 00278 $grade_item = grade_item::fetch(array('id'=>$aid, 'courseid'=>$courseid)); 00279 00280 if ($param === 'grademax' and $value < $grade_item->grademin) { 00281 // better not allow values lower than grade min 00282 $value = $grade_item->grademin; 00283 } 00284 $grade_item->$param = $value; 00285 00286 $grade_item->update(); 00287 grade_regrade_final_grades($courseid); 00288 00289 $recreatetree = true; 00290 00291 // Grade item checkbox inputs 00292 } elseif (preg_match('/^extracredit_([0-9]+)$/', $key, $matches)) { // Sum extra credit checkbox 00293 $aid = $matches[1]; 00294 $value = clean_param($value, PARAM_BOOL); 00295 00296 $grade_item = grade_item::fetch(array('id'=>$aid, 'courseid'=>$courseid)); 00297 $grade_item->aggregationcoef = $value; 00298 00299 $grade_item->update(); 00300 grade_regrade_final_grades($courseid); 00301 00302 $recreatetree = true; 00303 00304 // Grade category checkbox inputs 00305 } elseif (preg_match('/^aggregate(onlygraded|subcats|outcomes)_([0-9]+)$/', $key, $matches)) { 00306 $param = 'aggregate'.$matches[1]; 00307 $aid = $matches[2]; 00308 $value = clean_param($value, PARAM_BOOL); 00309 00310 $grade_category = grade_category::fetch(array('id'=>$aid, 'courseid'=>$courseid)); 00311 $grade_category->$param = $value; 00312 00313 $grade_category->update(); 00314 grade_regrade_final_grades($courseid); 00315 00316 $recreatetree = true; 00317 } 00318 } 00319 } 00320 00321 print_grade_page_head($courseid, 'edittree', $current_view, get_string('categoriesedit', 'grades') . ': ' . $current_view_str); 00322 00323 // Print Table of categories and items 00324 echo $OUTPUT->box_start('gradetreebox generalbox'); 00325 00326 echo '<form id="gradetreeform" method="post" action="'.$returnurl.'">'; 00327 echo '<div>'; 00328 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; 00329 00330 //did we update something in the db and thus invalidate $grade_edit_tree? 00331 if ($recreatetree) { 00332 $grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr); 00333 } 00334 00335 echo html_writer::table($grade_edit_tree->table); 00336 00337 echo '<div id="gradetreesubmit">'; 00338 if (!$moving) { 00339 echo '<input class="advanced" type="submit" value="'.get_string('savechanges').'" />'; 00340 } 00341 00342 // We don't print a bulk move menu if there are no other categories than course category 00343 if (!$moving && count($grade_edit_tree->categories) > 1) { 00344 echo '<br /><br />'; 00345 echo '<input type="hidden" name="bulkmove" value="0" id="bulkmoveinput" />'; 00346 echo get_string('moveselectedto', 'grades') . ' '; 00347 $attributes = array('id'=>'menumoveafter'); 00348 echo html_writer::select($grade_edit_tree->categories, 'moveafter', '', array(''=>'choosedots'), $attributes); 00349 $OUTPUT->add_action_handler(new component_action('change', 'submit_bulk_move'), 'menumoveafter'); 00350 echo '<div id="noscriptgradetreeform" class="hiddenifjs"> 00351 <input type="submit" value="'.get_string('go').'" /> 00352 </div>'; 00353 } 00354 00355 echo '</div>'; 00356 00357 echo '</div></form>'; 00358 00359 echo $OUTPUT->box_end(); 00360 00361 // Print action buttons 00362 echo $OUTPUT->container_start('buttons mdl-align'); 00363 00364 if ($moving) { 00365 echo $OUTPUT->single_button(new moodle_url('index.php', array('id'=>$course->id)), get_string('cancel'), 'get'); 00366 } else { 00367 echo $OUTPUT->single_button(new moodle_url('category.php', array('courseid'=>$course->id)), get_string('addcategory', 'grades'), 'get'); 00368 echo $OUTPUT->single_button(new moodle_url('item.php', array('courseid'=>$course->id)), get_string('additem', 'grades'), 'get'); 00369 00370 if (!empty($CFG->enableoutcomes)) { 00371 echo $OUTPUT->single_button(new moodle_url('outcomeitem.php', array('courseid'=>$course->id)), get_string('addoutcomeitem', 'grades'), 'get'); 00372 } 00373 00374 //echo $OUTPUT->(new moodle_url('index.php', array('id'=>$course->id, 'action'=>'autosort')), get_string('autosort', 'grades'), 'get'); 00375 } 00376 00377 echo $OUTPUT->container_end(); 00378 00379 echo $OUTPUT->footer(); 00380 00381 // Restore original show/hide preference if moving 00382 if ($moving) { 00383 $USER->gradeediting[$course->id] = $original_gradeediting; 00384 } 00385 die; 00386 00387