MDL-19404 Getting default values for grade_item object when creating a new grade_cate...
[moodle.git] / grade / edit / tree / lib.php
CommitLineData
dc482cfa 1<?php // $Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
11// //
12// This program is free software; you can redistribute it and/or modify //
13// it under the terms of the GNU General Public License as published by //
14// the Free Software Foundation; either version 2 of the License, or //
15// (at your option) any later version. //
16// //
17// This program is distributed in the hope that it will be useful, //
18// but WITHOUT ANY WARRANTY; without even the implied warranty of //
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20// GNU General Public License for more details: //
21// //
22// http://www.gnu.org/copyleft/gpl.html //
23// //
24///////////////////////////////////////////////////////////////////////////
25
26class grade_edit_tree {
27 public $columns = array();
28
29 /**
30 * @var object $gtree @see grade/lib.php
31 */
32 public $gtree;
33
34 /**
35 * @var grade_plugin_return @see grade/lib.php
36 */
37 public $gpr;
38
39 /**
40 * @var string $moving The eid of the category or item being moved
41 */
42 public $moving;
43
44 public $deepest_level;
45
653a8648 46 public $uses_extra_credit = false;
47
48 public $uses_weight = false;
49
dc482cfa 50 /**
51 * Constructor
52 */
53 public function __construct($gtree, $moving=false, $gpr) {
54 $this->gtree = $gtree;
55 $this->moving = $moving;
56 $this->gpr = $gpr;
57 $this->deepest_level = $this->get_deepest_level($this->gtree->top_element);
58
59 $this->columns = array(grade_edit_tree_column::factory('name', array('deepest_level' => $this->deepest_level)),
653a8648 60 grade_edit_tree_column::factory('aggregation', array('flag' => true)));
61
62 if ($this->uses_weight) {
63 $this->columns[] = grade_edit_tree_column::factory('weight', array('adv' => 'aggregationcoef'));
64 }
65 if ($this->uses_extra_credit) {
66 $this->columns[] = grade_edit_tree_column::factory('extracredit', array('adv' => 'aggregationcoef'));
67 }
68
69 $this->columns[] = grade_edit_tree_column::factory('range'); // This is not a setting... How do we deal with it?
70 $this->columns[] = grade_edit_tree_column::factory('aggregateonlygraded', array('flag' => true));
71 $this->columns[] = grade_edit_tree_column::factory('aggregatesubcats', array('flag' => true));
72 $this->columns[] = grade_edit_tree_column::factory('aggregateoutcomes', array('flag' => true));
73 $this->columns[] = grade_edit_tree_column::factory('droplow', array('flag' => true));
74 $this->columns[] = grade_edit_tree_column::factory('keephigh', array('flag' => true));
75 $this->columns[] = grade_edit_tree_column::factory('multfactor', array('adv' => true));
76 $this->columns[] = grade_edit_tree_column::factory('plusfactor', array('adv' => true));
77 $this->columns[] = grade_edit_tree_column::factory('actions');
78 $this->columns[] = grade_edit_tree_column::factory('select');
dc482cfa 79 }
80
81 /**
82 * Recursive function for building the table holding the grade categories and items,
83 * with CSS indentation and styles.
84 *
85 * @param array $element The current tree element being rendered
86 * @param boolean $totals Whether or not to print category grade items (category totals)
87 * @param array $parents An array of parent categories for the current element (used for indentation and row classes)
88 *
89 * @return string HTML
90 */
e8048b1d 91 public function build_html_tree($element, $totals, $parents, &$categories, $level, &$row_count) {
6b608f8f 92 global $CFG, $COURSE, $USER, $OUTPUT;
dc482cfa 93
94 $object = $element['object'];
95 $eid = $element['eid'];
96 $object->name = $this->gtree->get_element_header($element, true, true, false);
97 $object->stripped_name = $this->gtree->get_element_header($element, false, false, false);
98
99 $is_category_item = false;
100 if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') {
101 $is_category_item = true;
102 }
103
104 $rowclasses = '';
105 foreach ($parents as $parent_eid) {
106 $rowclasses .= " $parent_eid ";
107 }
108
109 $actions = '';
110
111 if (!$is_category_item) {
112 $actions .= $this->gtree->get_edit_icon($element, $this->gpr);
113 }
114
115 $actions .= $this->gtree->get_calculation_icon($element, $this->gpr);
116
117 if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) {
118 if ($this->element_deletable($element)) {
119 $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=delete&amp;eid='
6b608f8f 120 . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$OUTPUT->old_icon_url('t/delete') . '" class="iconsmall" alt="'
dc482cfa 121 . get_string('delete').'" title="'.get_string('delete').'"/></a>';
122 }
123 $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=moveselect&amp;eid='
6b608f8f 124 . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$OUTPUT->old_icon_url('t/move') . '" class="iconsmall" alt="'
dc482cfa 125 . get_string('move').'" title="'.get_string('move').'"/></a>';
126 }
127
128 $actions .= $this->gtree->get_hiding_icon($element, $this->gpr);
129 $actions .= $this->gtree->get_locking_icon($element, $this->gpr);
130
131 $mode = ($USER->gradeediting[$COURSE->id]) ? 'advanced' : 'simple';
132
133 $html = '';
134 $root = false;
135
136
137 $id = required_param('id', PARAM_INT);
138
139 /// prepare move target if needed
140 $last = '';
141
142 /// print the list items now
143 if ($this->moving == $eid) {
144
145 // do not diplay children
146 return '<tr><td colspan="12" class="'.$element['type'].' moving">'.$object->name.' ('.get_string('move').')</td></tr>';
147
148 }
149
150 if ($element['type'] == 'category') {
151 $level++;
152 $categories[$object->id] = $object->stripped_name;
153 $category = grade_category::fetch(array('id' => $object->id));
154 $item = $category->get_grade_item();
155
156 // Add aggregation coef input if not a course item and if parent category has correct aggregation type
fa5ac78b 157 $dimmed = ($item->is_hidden()) ? " dimmed " : "";
dc482cfa 158
159 // Before we print the category's row, we must find out how many rows will appear below it (for the filler cell's rowspan)
160 $aggregation_position = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition);
161 $category_total_data = null; // Used if aggregationposition is set to "last", so we can print it last
162
163 $html_children = '';
164
165 $row_count = 0;
166
167 foreach($element['children'] as $child_el) {
168 $moveto = '';
169
170 if (empty($child_el['object']->itemtype)) {
171 $child_el['object']->itemtype = false;
172 }
173
174 if (($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) {
175 continue;
176 }
177
178 $child_eid = $child_el['eid'];
179 $first = '';
180
181 if ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
182 $first = '&amp;first=1';
183 $child_eid = $eid;
184 }
185
186 if ($this->moving && $this->moving != $child_eid) {
187
188 $strmove = get_string('move');
189 $strmovehere = get_string('movehere');
190 $actions = ''; // no action icons when moving
191
192 $moveto = '<tr><td colspan="12"><a href="index.php?id='.$COURSE->id.'&amp;action=move&amp;eid='.$this->moving.'&amp;moveafter='
193 . $child_eid.'&amp;sesskey='.sesskey().$first.'"><img class="movetarget" src="'.$CFG->wwwroot.'/pix/movehere.gif" alt="'
1edd08ab 194 . s($strmovehere).'" title="'.s($strmovehere).'" /></a></td></tr>';
dc482cfa 195 }
196
197 $newparents = $parents;
198 $newparents[] = $eid;
199
200 $row_count++;
201 $child_row_count = 0;
202
203 // If moving, do not print course and category totals, but still print the moveto target box
204 if ($this->moving && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category')) {
205 $html_children .= $moveto;
206 } elseif ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
207 // We don't build the item yet because we first need to know the deepest level of categories (for category/name colspans)
208 $category_total_item = $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count);
209 if (!$aggregation_position) {
210 $html_children .= $category_total_item;
211 }
212 } else {
213 $html_children .= $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count) . $moveto;
214
215 if ($this->moving) {
216 $row_count++;
217 }
218 }
219
220 $row_count += $child_row_count;
221
222 // If the child is a category, increment row_count by one more (for the extra coloured row)
223 if ($child_el['type'] == 'category') {
224 $row_count++;
225 }
226 }
227
228 // Print category total at the end if aggregation position is "last" (1)
229 if (!empty($category_total_item) && $aggregation_position) {
230 $html_children .= $category_total_item;
231 }
232
233 // now build the header
234 if (isset($element['object']->grade_item) && $element['object']->grade_item->is_course_item()) {
235 // Reduce width if advanced elements are not shown
236 $width_style = '';
237
238 if ($mode == 'simple') {
239 $width_style = ' style="width:auto;" ';
240 }
241
b189277f 242 $html .= '<table id="grade_edit_tree_table" cellpadding="5" class="generaltable" '.$width_style.'>
dc482cfa 243 <tr>';
244
245 foreach ($this->columns as $column) {
246 if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
247 $html .= $column->get_header_cell();
248 }
249 }
250
251 $html .= '</tr>';
252 $root = true;
253 }
254
255 $row_count_offset = 0;
256
257 if (empty($category_total_item) && !$this->moving) {
258 $row_count_offset = -1;
259 }
260
261 $levelclass = " level$level ";
2be6ca78 262
b189277f 263 $courseclass = '';
264 if ($level == 1) {
265 $courseclass = 'coursecategory';
266 }
dc482cfa 267
268 $html .= '
b189277f 269 <tr class="'.$courseclass.' category '.$dimmed.$rowclasses.'">
1edd08ab 270 <th scope="row" title="'.s($object->stripped_name).'" class="cell rowspan '.$levelclass.'" rowspan="'.($row_count+1+$row_count_offset).'"></th>';
dc482cfa 271
272 foreach ($this->columns as $column) {
273 if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
274 $html .= $column->get_category_cell($category, $levelclass, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'eid' => $eid));
275 }
276 }
277
278 $html .= '</tr>';
279
280 $html .= $html_children;
281
282 // Print a coloured row to show the end of the category accross the table
283 $html .= '<tr><td colspan="'.(19 - $level).'" class="colspan '.$levelclass.'"></td></tr>';
284
285 } else { // Dealing with a grade item
286
287 $item = grade_item::fetch(array('id' => $object->id));
288 $element['type'] = 'item';
289 $element['object'] = $item;
2be6ca78 290
b189277f 291 $categoryitemclass = '';
292 if ($item->itemtype == 'category') {
293 $categoryitemclass = 'categoryitem';
294 }
dc482cfa 295
fa5ac78b 296 $dimmed = ($item->is_hidden()) ? " dimmed_text " : "";
b189277f 297 $html .= '<tr class="'.$categoryitemclass.' item'.$dimmed.$rowclasses.'">';
dc482cfa 298
299 foreach ($this->columns as $column) {
300 if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
301 $html .= $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions,
302 'element' => $element, 'eid' => $eid, 'itemtype' => $object->itemtype));
303 }
304 }
305
306 $html .= '</tr>';
307 }
308
309
310 if ($root) {
311 $html .= "</table>\n";
312 }
313
314 return $html;
315
316 }
317
318 /**
319 * Given a grade_item object, returns a labelled input if an aggregation coefficient (weight or extra credit) applies to it.
320 * @param grade_item $item
653a8648 321 * @param string type "extra" or "weight": the type of the column hosting the weight input
dc482cfa 322 * @return string HTML
323 */
653a8648 324 function get_weight_input($item, $type) {
dc482cfa 325 if (!is_object($item) || get_class($item) !== 'grade_item') {
326 throw new Exception('grade_edit_tree::get_weight_input($item) was given a variable that is not of the required type (grade_item object)');
327 return false;
328 }
329
330 if ($item->is_course_item()) {
331 return '';
332 }
333
334 $parent_category = $item->get_parent_category();
dc482cfa 335 $parent_category->apply_forced_settings();
653a8648 336 $aggcoef = $item->get_coefstring();
dc482cfa 337
653a8648 338 if ((($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoef') && $type == 'weight') ||
339 ($aggcoef == 'aggregationcoefextra' && $type == 'extra')) {
cd3a391c 340 return '<input type="text" size="6" id="aggregationcoef_'.$item->id.'" name="aggregationcoef_'.$item->id.'"
341 value="'.format_float($item->aggregationcoef, 4).'" />';
653a8648 342 } elseif ($aggcoef == 'aggregationcoefextrasum' && $type == 'extra') {
cd3a391c 343 $checked = ($item->aggregationcoef > 0) ? 'checked="checked"' : '';
344 return '<input type="hidden" name="extracredit_'.$item->id.'" value="0" />
345 <input type="checkbox" id="extracredit_'.$item->id.'" name="extracredit_'.$item->id.'" value="1" '."$checked />\n";
346 } else {
347 return '';
dc482cfa 348 }
cd3a391c 349 }
dc482cfa 350
351 /**
352 * Given an element of the grade tree, returns whether it is deletable or not (only manual grade items are deletable)
353 *
354 * @param array $element
355 * @return bool
356 */
357 function element_deletable($element) {
358 global $COURSE;
359
360 if ($element['type'] != 'item') {
361 return true;
362 }
363
364 $grade_item = $element['object'];
365
366 if ($grade_item->itemtype != 'mod' or $grade_item->is_outcome_item() or $grade_item->gradetype == GRADE_TYPE_NONE) {
367 return true;
368 }
369
370 $modinfo = get_fast_modinfo($COURSE);
371 if (!isset($modinfo->instances[$grade_item->itemmodule][$grade_item->iteminstance])) {
372 // module does not exist
373 return true;
374 }
375
376 return false;
377 }
378
379 /**
380 * Given the grade tree and an array of element ids (e.g. c15, i42), and expecting the 'moveafter' URL param,
381 * moves the selected items to the requested location. Then redirects the user to the given $returnurl
382 *
383 * @param object $gtree The grade tree (a recursive representation of the grade categories and grade items)
384 * @param array $eids
385 * @param string $returnurl
386 */
387 function move_elements($eids, $returnurl) {
388 $moveafter = required_param('moveafter', PARAM_INT);
389
390 if (!is_array($eids)) {
391 $eids = array($eids);
392 }
393
394 if(!$after_el = $this->gtree->locate_element("c$moveafter")) {
395 print_error('invalidelementid', '', $returnurl);
396 }
397
398 $after = $after_el['object'];
399 $parent = $after;
400 $sortorder = $after->get_sortorder();
401
402 foreach ($eids as $eid) {
403 if (!$element = $this->gtree->locate_element($eid)) {
404 print_error('invalidelementid', '', $returnurl);
405 }
406 $object = $element['object'];
407
408 $object->set_parent($parent->id);
409 $object->move_after_sortorder($sortorder);
410 }
411
412 redirect($returnurl, '', 0);
413 }
414
415 /**
416 * Recurses through the entire grade tree to find and return the maximum depth of the tree.
417 * This should be run only once from the root element (course category), and is used for the
418 * indentation of the Name column's cells (colspan)
419 *
420 * @param array $element An array of values representing a grade tree's element (all grade items in this case)
421 * @param int $level The level of the current recursion
422 * @param int $deepest_level A value passed to each subsequent level of recursion and incremented if $level > $deepest_level
423 * @return int Deepest level
424 */
425 function get_deepest_level($element, $level=0, $deepest_level=1) {
426 $object = $element['object'];
427
428 $level++;
653a8648 429 $coefstring = $element['object']->get_coefstring();
dc482cfa 430 if ($element['type'] == 'category') {
653a8648 431 if ($coefstring == 'aggregationcoefweight') {
432 $this->uses_weight = true;
433 } elseif ($coefstring == 'aggregationcoefextra' || $coefstring == 'aggregationcoefextrasum') {
434 $this->uses_extra_credit = true;
435 }
436
dc482cfa 437 foreach($element['children'] as $child_el) {
438 if ($level > $deepest_level) {
439 $deepest_level = $level;
440 }
441 $deepest_level = $this->get_deepest_level($child_el, $level, $deepest_level);
442 }
443 }
444
445 return $deepest_level;
446 }
447}
448
449abstract class grade_edit_tree_column {
450 public $forced;
451 public $hidden;
452 public $forced_hidden;
453 public $advanced_hidden;
454 public $hide_when_moving = true;
455
456 public static function factory($name, $params=array()) {
457 $class_name = "grade_edit_tree_column_$name";
458 if (class_exists($class_name)) {
459 return new $class_name($params);
460 }
461 }
462
463 public abstract function get_header_cell();
464
465 public abstract function get_category_cell($category, $levelclass, $params);
466
467 public abstract function get_item_cell($item, $params);
468
469 public abstract function is_hidden($mode='simple');
470}
471
472abstract class grade_edit_tree_column_category extends grade_edit_tree_column {
473
474 public $forced;
475 public $advanced;
476
477 public function __construct($name) {
478 global $CFG;
479 $this->forced = (int)$CFG->{"grade_$name"."_flag"} & 1;
480 $this->advanced = (int)$CFG->{"grade_$name"."_flag"} & 2;
481 }
482
483 public function is_hidden($mode='simple') {
484 global $CFG;
485 if ($mode == 'simple') {
486 return $this->advanced;
487 } elseif ($mode == 'advanced') {
488 if ($this->forced && $CFG->grade_hideforcedsettings) {
489 return true;
490 } else {
491 return false;
492 }
493 }
494 }
495}
496
497class grade_edit_tree_column_name extends grade_edit_tree_column {
498 public $forced = false;
499 public $hidden = false;
500 public $forced_hidden = false;
501 public $advanced_hidden = false;
502 public $deepest_level = 1;
503 public $hide_when_moving = false;
504
505 public function __construct($params) {
506 if (empty($params['deepest_level'])) {
507 throw new Exception('Tried to instantiate a grade_edit_tree_column_name object without the "deepest_level" param!');
508 }
509
510 $this->deepest_level = $params['deepest_level'];
511 }
512
513 public function get_header_cell() {
514 return '<th class="header name" colspan="'.($this->deepest_level + 1).'" scope="col">'.get_string('name').'</th>';
515 }
516
517 public function get_category_cell($category, $levelclass, $params) {
518 if (empty($params['name']) || empty($params['level'])) {
519 throw new Exception('Array key (name or level) missing from 3rd param of grade_edit_tree_column_name::get_category_cell($category, $levelclass, $params)');
520 }
521
522 return '<td class="cell name '.$levelclass.'" colspan="'.(($this->deepest_level +1) - $params['level']).'"><h4>' . $params['name'] . "</h4></td>\n";
523 }
524
525 public function get_item_cell($item, $params) {
526 global $CFG;
527
528 if (empty($params['element']) || empty($params['name']) || empty($params['level'])) {
529 throw new Exception('Array key (name, level or element) missing from 2nd param of grade_edit_tree_column_name::get_item_cell($item, $params)');
530 }
531
532 $name = $params['name'];
533
534 return '<td class="cell name" colspan="'.(($this->deepest_level + 1) - $params['level']).'">' . $name . '</td>';
535 }
536
537 public function is_hidden($mode='simple') {
538 return false;
539 }
540}
541
542class grade_edit_tree_column_aggregation extends grade_edit_tree_column_category {
543
544 public function __construct($params) {
545 parent::__construct('aggregation');
546 }
547
548 public function get_header_cell() {
549 return '<th class="header" scope="col">'.get_string('aggregation', 'grades').helpbutton('aggregation', 'aggregation', 'grade', true, false, '', true).'</th>';
550 }
551
552 public function get_category_cell($category, $levelclass, $params) {
653a8648 553 global $CFG;
dc482cfa 554 if (empty($params['id'])) {
555 throw new Exception('Array key (id) missing from 3rd param of grade_edit_tree_column_aggregation::get_category_cell($category, $levelclass, $params)');
556 }
557
558 $options = array(GRADE_AGGREGATE_MEAN => get_string('aggregatemean', 'grades'),
559 GRADE_AGGREGATE_WEIGHTED_MEAN => get_string('aggregateweightedmean', 'grades'),
560 GRADE_AGGREGATE_WEIGHTED_MEAN2 => get_string('aggregateweightedmean2', 'grades'),
561 GRADE_AGGREGATE_EXTRACREDIT_MEAN => get_string('aggregateextracreditmean', 'grades'),
562 GRADE_AGGREGATE_MEDIAN => get_string('aggregatemedian', 'grades'),
563 GRADE_AGGREGATE_MIN => get_string('aggregatemin', 'grades'),
564 GRADE_AGGREGATE_MAX => get_string('aggregatemax', 'grades'),
565 GRADE_AGGREGATE_MODE => get_string('aggregatemode', 'grades'),
566 GRADE_AGGREGATE_SUM => get_string('aggregatesum', 'grades'));
567
653a8648 568 $visible = explode(',', $CFG->grade_aggregations_visible);
569 foreach ($options as $constant => $string) {
570 if (!in_array($constant, $visible) && $constant != $category->aggregation) {
571 unset($options[$constant]);
572 }
573 }
574
575 $script = "window.location='index.php?id={$params['id']}&amp;category={$category->id}&amp;aggregationtype='+this.value+'&amp;sesskey=" . sesskey()."';";
d9ae2ab5 576 $aggregation = choose_from_menu($options, 'aggregation_'.$category->id, $category->aggregation, null, $script, 0, true);
dc482cfa 577
578 if ($this->forced) {
579 $aggregation = $options[$category->aggregation];
580 }
581
582 return '<td class="cell '.$levelclass.'">' . $aggregation . '</td>';
583
584 }
585
586 public function get_item_cell($item, $params) {
587 return '<td class="cell"> - </td>';
588 }
589}
590
653a8648 591class grade_edit_tree_column_extracredit extends grade_edit_tree_column {
592
593 public function get_header_cell() {
e3efd04c 594 return '<th class="header" scope="col">'.get_string('extracredit', 'grades').helpbutton('aggregationcoefcombo', 'aggregationcoefcombo', 'grade', true, false, '', true).'</th>';
653a8648 595 }
596
597 public function get_category_cell($category, $levelclass, $params) {
598
599 $item = $category->get_grade_item();
600 $aggcoef_input = grade_edit_tree::get_weight_input($item, 'extra');
601 return '<td class="cell '.$levelclass.'">' . $aggcoef_input . '</td>';
602 }
603
604 public function get_item_cell($item, $params) {
605 if (empty($params['element'])) {
606 throw new Exception('Array key (element) missing from 2nd param of grade_edit_tree_column_weightorextracredit::get_item_cell($item, $params)');
607 }
608
609 $html = '<td class="cell">';
610
611 if (!in_array($params['element']['object']->itemtype, array('courseitem', 'categoryitem', 'category'))) {
612 $html .= grade_edit_tree::get_weight_input($item, 'extra');
613 }
614
615 return $html.'</td>';
616 }
617
618 public function is_hidden($mode='simple') {
619 global $CFG;
620 if ($mode == 'simple') {
621 return strstr($CFG->grade_item_advanced, 'aggregationcoef');
622 } elseif ($mode == 'advanced') {
623 return false;
624 }
625 }
626}
627
628class grade_edit_tree_column_weight extends grade_edit_tree_column {
dc482cfa 629
630 public function get_header_cell() {
653a8648 631 return '<th class="header" scope="col">'.get_string('weightuc', 'grades').helpbutton('aggregationcoefweight', 'aggregationcoefweight', 'grade', true, false, '', true).'</th>';
dc482cfa 632 }
633
634 public function get_category_cell($category, $levelclass, $params) {
635
636 $item = $category->get_grade_item();
653a8648 637 $aggcoef_input = grade_edit_tree::get_weight_input($item, 'weight');
dc482cfa 638 return '<td class="cell '.$levelclass.'">' . $aggcoef_input . '</td>';
639 }
640
641 public function get_item_cell($item, $params) {
642 if (empty($params['element'])) {
643 throw new Exception('Array key (element) missing from 2nd param of grade_edit_tree_column_weightorextracredit::get_item_cell($item, $params)');
644 }
645
dc482cfa 646 $html = '<td class="cell">';
647
b8436ccb 648 if (!in_array($params['element']['object']->itemtype, array('courseitem', 'categoryitem', 'category'))) {
653a8648 649 $html .= grade_edit_tree::get_weight_input($item, 'weight');
dc482cfa 650 }
651
652 return $html.'</td>';
653 }
654
655 public function is_hidden($mode='simple') {
656 global $CFG;
657 if ($mode == 'simple') {
658 return strstr($CFG->grade_item_advanced, 'aggregationcoef');
659 } elseif ($mode == 'advanced') {
660 return false;
661 }
662 }
663}
664
665class grade_edit_tree_column_range extends grade_edit_tree_column {
666
667 public function get_header_cell() {
668 return '<th class="header" scope="col">'.get_string('maxgrade', 'grades').'</th>';
669 }
670
671 public function get_category_cell($category, $levelclass, $params) {
672 return '<td class="cell range '.$levelclass.'"> - </td>';
673 }
674
675 public function get_item_cell($item, $params) {
3998cc5c 676 global $DB;
46409b20 677
678 // If the parent aggregation is Sum of Grades, this cannot be changed
679 $parent_cat = $item->get_parent_category();
680 if ($parent_cat->aggregation == GRADE_AGGREGATE_SUM) {
681 $grademax = format_float($item->grademax, $item->get_decimals());
682 } elseif ($item->gradetype == GRADE_TYPE_SCALE) {
3998cc5c 683 $scale = $DB->get_record('scale', array('id' => $item->scaleid));
dc482cfa 684 $scale_items = explode(',', $scale->scale);
685 $grademax = end($scale_items) . ' (' . count($scale_items) . ')';
686 } elseif ($item->is_external_item()) {
687 $grademax = format_float($item->grademax, $item->get_decimals());
688 } else {
cd3a391c 689 $grademax = '<input type="text" size="4" id="grademax'.$item->id.'" name="grademax_'.$item->id.'" value="'.format_float($item->grademax, $item->get_decimals()).'" />';
dc482cfa 690 }
691
692 return '<td class="cell">'.$grademax.'</td>';
693 }
694
695 public function is_hidden($mode='simple') {
696 global $CFG;
697 if ($mode == 'simple') {
698 return strstr($CFG->grade_item_advanced, 'grademax');
699 } elseif ($mode == 'advanced') {
700 return false;
701 }
702 }
703}
704
705class grade_edit_tree_column_aggregateonlygraded extends grade_edit_tree_column_category {
706
707 public function __construct($params) {
708 parent::__construct('aggregateonlygraded');
709 }
710
711 public function get_header_cell() {
712 return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregateonlygraded', 'grades')
713 .helpbutton('aggregateonlygraded', 'aggregateonlygraded', 'grade', true, false, '', true).'</th>';
714 }
715
716 public function get_category_cell($category, $levelclass, $params) {
717 $onlygradedcheck = ($category->aggregateonlygraded == 1) ? 'checked="checked"' : '';
cd3a391c 718 $hidden = '<input type="hidden" name="aggregateonlygraded_'.$category->id.'" value="0" />';
719 $aggregateonlygraded ='<input type="checkbox" id="aggregateonlygraded_'.$category->id.'" name="aggregateonlygraded_'.$category->id.'" value="1" '.$onlygradedcheck . ' />';
dc482cfa 720
721 if ($this->forced) {
722 $aggregateonlygraded = ($category->aggregateonlygraded) ? get_string('yes') : get_string('no');
723 }
724
cd3a391c 725 return '<td class="cell '.$levelclass.'">'.$hidden.$aggregateonlygraded.'</td>';
dc482cfa 726 }
727
728 public function get_item_cell($item, $params) {
729 return '<td class="cell"> - </td>';
730 }
731}
732
733class grade_edit_tree_column_aggregatesubcats extends grade_edit_tree_column_category {
734
735 public function __construct($params) {
736 parent::__construct('aggregatesubcats');
737 }
738
739 public function get_header_cell() {
740 return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregatesubcats', 'grades')
741 .helpbutton('aggregatesubcats', 'aggregatesubcats', 'grade', true, false, '', true).'</th>';
742 }
743
744 public function get_category_cell($category, $levelclass, $params) {
745 $subcatscheck = ($category->aggregatesubcats == 1) ? 'checked="checked"' : '';
cd3a391c 746 $hidden = '<input type="hidden" name="aggregatesubcats_'.$category->id.'" value="0" />';
747 $aggregatesubcats = '<input type="checkbox" id="aggregatesubcats_'.$category->id.'" name="aggregatesubcats_'.$category->id.'" value="1" ' . $subcatscheck.' />';
dc482cfa 748
749 if ($this->forced) {
750 $aggregatesubcats = ($category->aggregatesubcats) ? get_string('yes') : get_string('no');
751 }
752
cd3a391c 753 return '<td class="cell '.$levelclass.'">'.$hidden.$aggregatesubcats.'</td>';
dc482cfa 754
755 }
756
757 public function get_item_cell($item, $params) {
758 return '<td class="cell"> - </td>';
759 }
760}
761
762class grade_edit_tree_column_aggregateoutcomes extends grade_edit_tree_column_category {
763
764 public function __construct($params) {
765 parent::__construct('aggregateoutcomes');
766 }
767
768 public function get_header_cell() {
769 return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregateoutcomes', 'grades')
770 .helpbutton('aggregateoutcomes', 'aggregateoutcomes', 'grade', true, false, '', true).'</th>';
771 }
772
773 public function get_category_cell($category, $levelclass, $params) {
774
775 $outcomescheck = ($category->aggregateoutcomes == 1) ? 'checked="checked"' : '';
cd3a391c 776 $hidden = '<input type="hidden" name="aggregateoutcomes_'.$category->id.'" value="0" />';
777 $aggregateoutcomes = '<input type="checkbox" id="aggregateoutcomes_'.$category->id.'" name="aggregateoutcomes_'.$category->id.'" value="1" ' . $outcomescheck.' />';
dc482cfa 778
779 if ($this->forced) {
780 $aggregateoutcomes = ($category->aggregateoutcomes) ? get_string('yes') : get_string('no');
781 }
782
cd3a391c 783 return '<td class="cell '.$levelclass.'">'.$hidden.$aggregateoutcomes.'</td>';
dc482cfa 784 }
785
786 public function get_item_cell($item, $params) {
787 return '<td class="cell"> - </td>';
788 }
789
790 public function is_hidden($mode='simple') {
791 global $CFG;
792 if ($CFG->enableoutcomes) {
793 return parent::is_hidden($mode);
794 } else {
795 return true;
796 }
797 }
798}
799
800class grade_edit_tree_column_droplow extends grade_edit_tree_column_category {
801
802 public function __construct($params) {
803 parent::__construct('droplow');
804 }
805
806 public function get_header_cell() {
807 return '<th class="header" scope="col">'.get_string('droplow', 'grades').helpbutton('droplow', 'droplow', 'grade', true, false, '', true).'</th>';
808 }
809
810 public function get_category_cell($category, $levelclass, $params) {
811 $droplow = '<input type="text" size="3" id="droplow_'.$category->id.'" name="droplow_'.$category->id.'" value="'.$category->droplow.'" />';
812
813 if ($this->forced) {
814 $droplow = $category->droplow;
815 }
816
817 return '<td class="cell '.$levelclass.'">' . $droplow . '</td>';
818 }
819
820 public function get_item_cell($item, $params) {
821 return '<td class="cell"> - </td>';
822 }
823}
824
825class grade_edit_tree_column_keephigh extends grade_edit_tree_column_category {
826
827 public function __construct($params) {
828 parent::__construct('keephigh');
829 }
830
831 public function get_header_cell() {
832 return '<th class="header" scope="col">'.get_string('keephigh', 'grades').helpbutton('keephigh', 'keephigh', 'grade', true, false, '', true).'</th>';
833 }
834
835 public function get_category_cell($category, $levelclass, $params) {
836 $keephigh = '<input type="text" size="3" id="keephigh_'.$category->id.'" name="keephigh_'.$category->id.'" value="'.$category->keephigh.'" />';
837
838 if ($this->forced) {
839 $keephigh = $category->keephigh;
840 }
841
842 return '<td class="cell '.$levelclass.'">' . $keephigh . '</td>';
843 }
844
845 public function get_item_cell($item, $params) {
846 return '<td class="cell"> - </td>';
847 }
848}
849
850class grade_edit_tree_column_multfactor extends grade_edit_tree_column {
851
852 public function __construct($params) {
853
854 }
855
856 public function get_header_cell() {
857 return '<th class="header" scope="col">'.get_string('multfactor', 'grades').helpbutton('multfactor', 'multfactor', 'grade', true, false, '', true).'</th>';
858 }
859
860 public function get_category_cell($category, $levelclass, $params) {
861
862 return '<td class="cell '.$levelclass.'"> - </td>';
863 }
864
865 public function get_item_cell($item, $params) {
a043086f 866 if (!$item->is_raw_used()) {
867 return '<td class="cell">&nbsp;</td>';
868 }
cd3a391c 869 $multfactor = '<input type="text" size="4" id="multfactor'.$item->id.'" name="multfactor_'.$item->id.'" value="'.format_float($item->multfactor, 4).'" />';
dc482cfa 870 return '<td class="cell">'.$multfactor.'</td>';
871 }
872
873 public function is_hidden($mode='simple') {
874 global $CFG;
875 if ($mode == 'simple') {
876 return strstr($CFG->grade_item_advanced, 'multfactor');
877 } elseif ($mode == 'advanced') {
878 return false;
879 }
880 }
881}
882
883class grade_edit_tree_column_plusfactor extends grade_edit_tree_column {
884
885 public function get_header_cell() {
886 return '<th class="header" scope="col">'.get_string('plusfactor', 'grades').helpbutton('plusfactor', 'plusfactor', 'grade', true, false, '', true).'</th>';
887 }
888
889 public function get_category_cell($category, $levelclass, $params) {
890 return '<td class="cell '.$levelclass.'"> - </td>';
891
892 }
893
894 public function get_item_cell($item, $params) {
a043086f 895 if (!$item->is_raw_used()) {
896 return '<td class="cell">&nbsp;</td>';
897 }
cd3a391c 898 $plusfactor = '<input type="text" size="4" id="plusfactor_'.$item->id.'" name="plusfactor_'.$item->id.'" value="'.format_float($item->plusfactor, 4).'" />';
dc482cfa 899 return '<td class="cell">'.$plusfactor.'</td>';
900
901 }
902
903 public function is_hidden($mode='simple') {
904 global $CFG;
905 if ($mode == 'simple') {
906 return strstr($CFG->grade_item_advanced, 'plusfactor');
907 } elseif ($mode == 'advanced') {
908 return false;
909 }
910 }
911}
912
913class grade_edit_tree_column_actions extends grade_edit_tree_column {
914
915 public function __construct($params) {
916
917 }
918
919 public function get_header_cell() {
920 return '<th class="header actions" scope="col">'.get_string('actions').'</th>';
921 }
922
923 public function get_category_cell($category, $levelclass, $params) {
924
925 if (empty($params['actions'])) {
926 throw new Exception('Array key (actions) missing from 3rd param of grade_edit_tree_column_actions::get_category_actions($category, $levelclass, $params)');
927 }
928
929 return '<td class="cell actions '.$levelclass.'">' . $params['actions'] . '</td>';
930 }
931
932 public function get_item_cell($item, $params) {
933 if (empty($params['actions'])) {
934 throw new Exception('Array key (actions) missing from 2nd param of grade_edit_tree_column_actions::get_item_cell($item, $params)');
935 }
936 return '<td class="cell actions">' . $params['actions'] . '</td>';
937 }
938
939 public function is_hidden($mode='simple') {
940 return false;
941 }
942}
943
944class grade_edit_tree_column_select extends grade_edit_tree_column {
945
946 public function get_header_cell() {
947 return '<th class="header selection" scope="col">'.get_string('select').'</th>';
948 }
949
950 public function get_category_cell($category, $levelclass, $params) {
951
952 if (empty($params['eid'])) {
953 throw new Exception('Array key (eid) missing from 3rd param of grade_edit_tree_column_select::get_category_cell($category, $levelclass, $params)');
954 }
955
956 return '<td class="cell last '.$levelclass.'" style="text-align: center">
957 <span class="actionlink" onclick="togglecheckboxes(\''.$params['eid'].'\', true);">'.get_string('all').'</span><br />
958 <span class="actionlink" onclick="togglecheckboxes(\''.$params['eid'].'\', false);">'.get_string('none').'</span>
959 </td>';
960 }
961
962 public function get_item_cell($item, $params) {
963 if (empty($params['itemtype']) || empty($params['eid'])) {
964 throw new Exception('Array key (itemtype or eid) missing from 2nd param of grade_edit_tree_column_select::get_item_cell($item, $params)');
965 }
966 $itemselect = '';
967
968 if ($params['itemtype'] != 'course' && $params['itemtype'] != 'category') {
2be6ca78 969 $itemselect = '<input class="itemselect" type="checkbox" name="select_'.$params['eid'].'" onchange="toggleCategorySelector();"/>';
dc482cfa 970 }
971 return '<td class="cell last selection">' . $itemselect . '</td>';
972 }
973
974 public function is_hidden($mode='simple') {
975 return false;
976 }
977}
978?>