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