Fix strings
[moodle.git] / question / category_class.php
CommitLineData
107e7612 1<?php // $Id$
516cf3eb 2/**
bc649d80 3 * Class question_category_object
4 *
5 * Used for handling changes to the question categories
6 *
7 * @version $Id$
8 * @author Martin Dougiamas and many others. {@link http://moodle.org}
9 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
10 * @package question
11 */
516cf3eb 12
13// number of categories to display on page
14define( "PAGE_LENGTH",25 );
15
dc1f00de 16class question_category_object {
516cf3eb 17
18 var $str;
19 var $pixpath;
20 var $edittable;
21 var $newtable;
22 var $tab;
23 var $tabsize = 3;
24 var $categories;
25 var $categorystrings;
26 var $defaultcategory;
27 var $course;
28 var $topcount;
29
bc649d80 30 /**
31 * Constructor
32 *
33 * Gets necessary strings and sets relevant path information
34 */
dc1f00de 35 function question_category_object() {
516cf3eb 36 global $CFG;
37
38 $this->tab = str_repeat('&nbsp;', $this->tabsize);
39
40 $this->str->course = get_string('course');
41 $this->str->category = get_string('category', 'quiz');
42 $this->str->categoryinfo = get_string('categoryinfo', 'quiz');
43 $this->str->questions = get_string('questions', 'quiz');
44 $this->str->add = get_string('add');
45 $this->str->delete = get_string('delete');
46 $this->str->moveup = get_string('moveup');
47 $this->str->movedown = get_string('movedown');
48 $this->str->edit = get_string('editthiscategory');
49 $this->str->hide = get_string('hide');
50 $this->str->publish = get_string('publish', 'quiz');
51 $this->str->order = get_string('order');
52 $this->str->parent = get_string('parent', 'quiz');
53 $this->str->add = get_string('add');
54 $this->str->action = get_string('action');
55 $this->str->top = get_string('top', 'quiz');
56 $this->str->addcategory = get_string('addcategory', 'quiz');
57 $this->str->editcategory = get_string('editcategory', 'quiz');
58 $this->str->cancel = get_string('cancel');
59 $this->str->editcategories = get_string('editcategories', 'quiz');
2befe778 60 $this->str->page = get_string('page');
516cf3eb 61 $this->pixpath = $CFG->pixpath;
62
63 }
64
bc649d80 65 /**
66 * Sets the course for this object
67 *
68 * @param object course
69 */
516cf3eb 70 function set_course($course) {
71 $this->course = $course;
72 }
73
bc649d80 74 /**
75 * Displays the user interface
76 *
77 * @param object modform
78 * @param int $page page number to display (0=don't paginate)
79 */
516cf3eb 80 function display_user_interface($page=0) {
81 $this->initialize();
82
83 /// Interface for adding a new category:
84 print_heading_with_help($this->str->addcategory, 'categories_edit', 'quiz');
85 $this->output_new_table();
86 echo '<br />';
87
88 /// Interface for editing existing categories
89 print_heading_with_help($this->str->editcategories, 'categories', 'quiz');
90 $this->output_edit_table($page);
91 if ($this->topcount>PAGE_LENGTH) {
92 $this->display_page_numbers($page);
93 }
94 echo '<br />';
95
96 }
97
98
bc649d80 99 /**
100 * Initializes this classes general category-related variables
101 */
516cf3eb 102 function initialize() {
103
104 /// Get the existing categories
4f48fb42 105 if (!$this->defaultcategory = get_default_question_category($this->course->id)) {
516cf3eb 106 error("Error: Could not find or make a category!");
107 }
108
dc1f00de 109 $this->categories = $this->get_question_categories(null, "parent, sortorder, name ASC");
516cf3eb 110
111 $this->categories = $this->arrange_categories($this->categories);
112
113 // create the array of id=>full_name strings
114 $this->categorystrings = $this->expanded_category_strings($this->categories);
115
116 // for pagination calculate number of 'top' categories and hence number of pages
117 // (pagination only based on top categories)
118 $count = 0;
119 foreach( $this->categories as $category ) {
120 if ($category->parent==0) {
121 ++$count;
122 }
123 }
124 $this->topcount = $count;
125 $this->pagecount = (integer) ceil( $count / PAGE_LENGTH );
126 }
127
bc649d80 128 /**
129 * display list of page numbers for navigation
130 */
516cf3eb 131 function display_page_numbers( $page=0 ) {
132 global $USER;
133
134 echo "<div class=\"paging\">{$this->str->page}:\n";
135 foreach (range(1,$this->pagecount) as $currentpage) {
136 if ($page == $currentpage) {
137 echo " $currentpage \n";
138 }
139 else {
140 echo "<a href=\"category.php?id={$this->course->id}&amp;page=$currentpage&amp;sesskey={$USER->sesskey}\">";
141 echo " $currentpage </a>\n";
142 }
143 }
144 echo "</div>";
145 }
146
bc649d80 147 /**
148 * Outputs a table to allow entry of a new category
149 */
516cf3eb 150 function output_new_table() {
151 global $USER;
152 $publishoptions[0] = get_string("no");
153 $publishoptions[1] = get_string("yes");
154
155 $this->newtable->head = array ($this->str->parent, $this->str->category, $this->str->categoryinfo, $this->str->publish, $this->str->action);
156 $this->newtable->width = 200;
157 $this->newtable->data[] = array();
158 $this->newtable->tablealign = 'center';
159
160 /// Each section below adds a data cell to the table row
161
162
163 $viableparents[0] = $this->str->top;
164 $viableparents = $viableparents + $this->categorystrings;
165 $this->newtable->align['parent'] = "left";
166 $this->newtable->wrap['parent'] = "nowrap";
167 $row['parent'] = choose_from_menu ($viableparents, "newparent", $this->str->top, "", "", "", true);
168
169 $this->newtable->align['category'] = "left";
170 $this->newtable->wrap['category'] = "nowrap";
171 $row['category'] = '<input type="text" name="newcategory" value="" size="15" />';
172
173 $this->newtable->align['info'] = "left";
174 $this->newtable->wrap['info'] = "nowrap";
175 $row['info'] = '<input type="text" name="newinfo" value="" size="50" />';
176
177 $this->newtable->align['publish'] = "left";
178 $this->newtable->wrap['publish'] = "nowrap";
179 $row['publish'] = choose_from_menu ($publishoptions, "newpublish", "", "", "", "", true);
180
181 $this->newtable->align['action'] = "left";
182 $this->newtable->wrap['action'] = "nowrap";
183 $row['action'] = '<input type="submit" value="' . $this->str->add . '" />';
184
185
186 $this->newtable->data[] = $row;
187
188 // wrap the table in a form and output it
189 echo '<form action="category.php" method="post">';
190 echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
191 echo '<input type="hidden" name="id" value="'. $this->course->id . '" />';
192 echo '<input type="hidden" name="addcategory" value="true" />';
193 print_table($this->newtable);
194 echo '</form>';
195 }
196
bc649d80 197 /**
198 * Outputs a table to allow editing/rearranging of existing categories
199 *
200 * $this->initialize() must have already been called
201 *
202 * @param object course
203 * @param int $page page to display (0=do not paginate)
204 */
516cf3eb 205 function output_edit_table($page=0) {
206 $this->edittable->head = array ($this->str->category, $this->str->categoryinfo, $this->str->questions, $this->str->publish,
207 $this->str->delete, $this->str->order, $this->str->parent);
208 $this->edittable->width = 200;
209 $this->edittable->tablealign = 'center';
210
211 $courses = $this->course->shortname;
212
213 // if pagination required work out range
214 if (!empty($page)) {
215 $firstcat = ($page-1) * PAGE_LENGTH + 1;
216 $lastcat = $firstcat + PAGE_LENGTH - 1;
217 }
218 else {
219 $firstcat = 1;
220 $lastcat = $this->topcount;
221 }
222//echo "$firstcat $lastcat $page"; die;
223 $this->build_edit_table_body($this->categories, $page, $firstcat, $lastcat);
224 print_table($this->edittable);
225 }
bc649d80 226
227 /**
228 * Recursively builds up the edit-categories table body
229 *
230 * @param array categories contains category objects in a tree representation
231 * @param mixed courses String with shortname of course | array containing courseid=>shortname
232 * @param int depth controls the indenting
233 */
516cf3eb 234 function build_edit_table_body($categories, $page = 0, $firstcat = 1, $lastcat = 99999, $depth = 0) {
235 $countcats = count($categories);
236 $count = 0;
237 $first = true;
238 $last = false;
239 $topcount = 0;
240
241 foreach ($categories as $category) {
242 $count++;
243 if ($count == $countcats) {
244 $last = true;
245 }
246 // check if this category is on the display page
247 if ($depth==0) {
248 $topcount++;
249 if (($topcount<$firstcat) or ($topcount>$lastcat)) {
250 continue;
251 }
252 }
253 $up = $first ? false : true;
254 $down = $last ? false : true;
255 $first = false;
f5565b69 256 $this->edit_question_category_row($category, $depth, $up, $down, $page);
516cf3eb 257 if (isset($category->children)) {
258 $this->build_edit_table_body($category->children, $page, $firstcat, $lastcat, $depth + 1);
259 }
260 }
261 }
262
bc649d80 263 /**
264 * gets all the courseids for the given categories
265 *
266 * @param array categories contains category objects in a tree representation
267 * @return array courseids flat array in form categoryid=>courseid
268 */
516cf3eb 269 function get_course_ids($categories) {
270 $courseids = array();
271 foreach ($categories as $key=>$cat) {
272 $courseids[$key] = $cat->course;
273 if (!empty($cat->children)) {
274 $courseids = array_merge($courseids, $this->get_course_ids($cat->children));
275 }
276 }
277 return $courseids;
278 }
279
bc649d80 280 /**
281 * Constructs each row of the edit-categories table
282 *
283 * @param object category
284 * @param int depth controls the indenting
285 * @param string shortname short name of the course
286 * @param boolean up can it be moved up?
287 * @param boolean down can it be moved down?
288 * @param int page page number
289 */
f5565b69 290 function edit_question_category_row($category, $depth, $up = false, $down = false, $page = 0) {
516cf3eb 291 global $USER;
292 $fill = str_repeat($this->tab, $depth);
293
d4228481 294 $linkcss = $category->publish ? ' class="published" ' : ' class="unpublished" ';
516cf3eb 295
296 if (!empty($page)) {
297 $pagelink="&amp;page=$page";
298 }
299 else {
300 $pagelink="";
301 }
302
303 /// Each section below adds a data cell to this table row
304
305 $this->edittable->align["$category->id.name"] = "left";
306 $this->edittable->wrap["$category->id.name"] = "nowrap";
8b9e8fc3 307 $row["$category->id.name"] = '<a ' . $linkcss . ' title="' . $this->str->edit. '" href="category.php?id=' . $this->course->id .
0d905d9f 308 '&amp;edit=' . $category->id . '&amp;sesskey='.$USER->sesskey.$pagelink.'"><img src="' . $this->pixpath . '/t/edit.gif" class="iconsmall"
516cf3eb 309 alt="' .$this->str->edit. '" /> ' . $fill . $category->name . '</a>';
310
311 $this->edittable->align["$category->id.info"] = "left";
312 $this->edittable->wrap["$category->id.info"] = "nowrap";
8b9e8fc3 313 $row["$category->id.info"] = '<a ' . $linkcss . ' title="' . $this->str->edit .'" href="category.php?id=' . $this->course->id .
516cf3eb 314 '&amp;edit=' . $category->id . '&amp;sesskey='.$USER->sesskey.$pagelink.'">' . $category->info . '</a>';
315
316 $this->edittable->align["$category->id.qcount"] = "center";
317 $row["$category->id.qcount"] = $category->questioncount;
318
319 $this->edittable->align["$category->id.publish"] = "center";
320 $this->edittable->wrap["$category->id.publish"] = "nowrap";
321 if (!empty($category->publish)) {
322 $row["$category->id.publish"] = '<a title="' . $this->str->hide . '" href="category.php?id=' . $this->course->id . '&amp;hide=' . $category->id .
0d905d9f 323 '&amp;sesskey='.$USER->sesskey.$pagelink.'"><img src="' . $this->pixpath . '/t/hide.gif" class="iconsmall" alt="' .$this->str->hide. '" /></a> ';
516cf3eb 324 } else {
325 $row["$category->id.publish"] = '<a title="' . $this->str->publish . '" href="category.php?id=' . $this->course->id . '&amp;publish=' . $category->id .
0d905d9f 326 '&amp;sesskey='.$USER->sesskey.$pagelink.'"><img src="' . $this->pixpath . '/t/show.gif" class="iconsmall" alt="' .$this->str->publish. '" /></a> ';
516cf3eb 327 }
328
329 if ($category->id != $this->defaultcategory->id) {
330 $this->edittable->align["$category->id.delete"] = "center";
331 $this->edittable->wrap["$category->id.delete"] = "nowrap";
332 $row["$category->id.delete"] = '<a title="' . $this->str->delete . '" href="category.php?id=' . $this->course->id .
0d905d9f 333 '&amp;delete=' . $category->id . '&amp;sesskey='.$USER->sesskey.$pagelink.'"><img src="' . $this->pixpath . '/t/delete.gif" class="iconsmall" alt="' .$this->str->delete. '" /></a> ';
516cf3eb 334 } else {
335 $row["$category->id.delete"] = '';
336 }
337
338 $this->edittable->align["$category->id.order"] = "left";
339 $this->edittable->wrap["$category->id.order"] = "nowrap";
340 $icons = '';
341 if ($up) {
342 $icons .= '<a title="' . $this->str->moveup .'" href="category.php?id=' . $this->course->id . '&amp;moveup=' . $category->id . '&amp;sesskey='.$USER->sesskey.$pagelink.'">
0d905d9f 343 <img src="' . $this->pixpath . '/t/up.gif" class="iconsmall" alt="' . $this->str->moveup. '" /></a> ';
516cf3eb 344 }
345 if ($down) {
346 $icons .= '<a title="' . $this->str->movedown .'" href="category.php?id=' . $this->course->id . '&amp;movedown=' . $category->id . '&amp;sesskey='.$USER->sesskey.$pagelink.'">
0d905d9f 347 <img src="' . $this->pixpath . '/t/down.gif" class="iconsmall" alt="' .$this->str->movedown. '" /></a> ';
516cf3eb 348 }
349 $row["$category->id.order"]= $icons;
350
351 $this->edittable->align["$category->id.moveto"] = "left";
352 $this->edittable->wrap["$category->id.moveto"] = "nowrap";
353 if ($category->id != $this->defaultcategory->id) {
354 $viableparents = $this->categorystrings;
355 $this->set_viable_parents($viableparents, $category);
356 $viableparents = array(0=>$this->str->top) + $viableparents;
357
358 $row["$category->id.moveto"] = popup_form ("category.php?id={$this->course->id}&amp;move={$category->id}&amp;sesskey=$USER->sesskey$pagelink&amp;moveto=",
359 $viableparents, "moveform{$category->id}", "$category->parent", "", "", "", true);
360 } else {
361 $row["$category->id.moveto"]='---';
362 }
363
364
365 $this->edittable->data[$category->id] = $row;
366 }
367
368
369 function edit_single_category($categoryid,$page=1) {
370 /// Interface for adding a new category
371 global $USER;
372 $this->initialize();
373
374 /// Interface for editing existing categories
dc1f00de 375 if ($category = get_record("question_categories", "id", $categoryid)) {
516cf3eb 376 echo '<h2 align="center">';
377 echo $this->str->edit;
378 helpbutton("categories_edit", $this->str->editcategory, "quiz");
379 echo '</h2>';
380 echo '<table width="100%"><tr><td>';
381 $this->output_edit_single_table($category,$page);
382 echo '</td></tr></table>';
383 echo '<p><div align="center"><form action="category.php" method="get">
384 <input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />
385 <input type="hidden" name="id" value="' . $this->course->id . '" />
386 <input type="submit" value="' . $this->str->cancel . '" /></form></div></p>';
387 print_footer($this->course);
388 exit;
389 } else {
390 error("Category $categoryid not found", "category.php?id={$this->course->id}");
391 }
392 }
393
bc649d80 394 /**
395 * Outputs a table to allow editing of an existing category
396 *
397 * @param object category
398 * @param int page current page
399 */
516cf3eb 400 function output_edit_single_table($category, $page=1) {
401 global $USER;
402 $publishoptions[0] = get_string("no");
403 $publishoptions[1] = get_string("yes");
404 $strupdate = get_string('update');
405
4abc23b2 406 $edittable = new stdClass;
516cf3eb 407
408 $edittable->head = array ($this->str->parent, $this->str->category, $this->str->categoryinfo, $this->str->publish, $this->str->action);
409 $edittable->width = 200;
410 $edittable->data[] = array();
411 $edittable->tablealign = 'center';
412
413 /// Each section below adds a data cell to the table row
414
415 $viableparents = $this->categorystrings;
416 $this->set_viable_parents($viableparents, $category);
417 $viableparents = array(0=>$this->str->top) + $viableparents;
418 $edittable->align['parent'] = "left";
419 $edittable->wrap['parent'] = "nowrap";
420 $row['parent'] = choose_from_menu ($viableparents, "updateparent", "{$category->parent}", "", "", "", true);
421
422 $edittable->align['category'] = "left";
423 $edittable->wrap['category'] = "nowrap";
424 $row['category'] = '<input type="text" name="updatename" value="' . $category->name . '" size="15" />';
425
426 $edittable->align['info'] = "left";
427 $edittable->wrap['info'] = "nowrap";
428 $row['info'] = '<input type="text" name="updateinfo" value="' . $category->info . '" size="50" />';
429
430 $edittable->align['publish'] = "left";
431 $edittable->wrap['publish'] = "nowrap";
432 $selected = (boolean)$category->publish ? 1 : 0;
433 $row['publish'] = choose_from_menu ($publishoptions, "updatepublish", $selected, "", "", "", true);
434
435 $edittable->align['action'] = "left";
436 $edittable->wrap['action'] = "nowrap";
437 $row['action'] = '<input type="submit" value="' . $strupdate . '" />';
438
439 $edittable->data[] = $row;
440
441 // wrap the table in a form and output it
442 echo '<p><form action="category.php" method="post">';
443 echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
444 echo '<input type="hidden" name="id" value="'. $this->course->id . '" />';
445 echo '<input type="hidden" name="updateid" value="' . $category->id . '" />';
446 echo "<input type=\"hidden\" name=\"page\" value=\"$page\" />";
447 print_table($edittable);
448 echo '</form></p>';
449 }
450
bc649d80 451 /**
452 * Creates an array of "full-path" category strings
453 * Structure:
454 * key => string
455 * where key is the category id, and string contains the name of all ancestors as well as the particular category name
456 * E.g. '123'=>'Language / English / Grammar / Modal Verbs"
457 *
458 * @param array $categories an array containing categories arranged in a tree structure
459 */
516cf3eb 460 function expanded_category_strings($categories, $parent=null) {
461 $prefix = is_null($parent) ? '' : "$parent / ";
462 $categorystrings = array();
463 foreach ($categories as $key => $category) {
464 $expandedname = "$prefix$category->name";
465 $categorystrings[$key] = $expandedname;
466 if (isset($category->children)) {
467 $categorystrings = $categorystrings + $this->expanded_category_strings($category->children, $expandedname);
468 }
469 }
470 return $categorystrings;
471 }
472
bc649d80 473 /**
474 * Arranges the categories into a hierarchical tree
475 *
476 * If a category has children, it's "children" property holds an array of children
477 * The questioncount for each category is also calculated
478 *
479 * @param array records a flat list of the categories
480 * @return array categorytree a hierarchical list of the categories
481 */
516cf3eb 482 function arrange_categories($records) {
4f48fb42 483 //TODO: get the question count for all records with one sql statement: select category, count(*) from question group by category
516cf3eb 484 $levels = array();
485
486 // build a levels array, which places each record according to it's depth from the top level
487 $parents = array(0);
488 while (!empty($parents)) {
489 $children = array();
490 foreach ($records as $record) {
491 if (in_array($record->parent, $parents)) {
492 $children[] = $record->id;
493 }
494 }
495 if (!empty($children)) {
496 $levels[] = $children;
497 }
498 $parents = $children;
499 }
500 // if there is no hierarchy (e.g., if all records have parent == 0), set level[0] to these keys
501 if (empty($levels)) {
502 $levels[0] = array_keys($records);
503 }
504
505 // build a hierarchical array that depicts the parent-child relationships of the categories
506 $categorytree = array();
507 for ($index = count($levels) - 1; $index >= 0; $index--) {
508 foreach($levels[$index] as $key) {
509 $parentkey = $records[$key]->parent;
4f48fb42 510 if (!($records[$key]->questioncount = count_records('question', 'category', $records[$key]->id, 'hidden', 0, 'parent', '0'))) {
516cf3eb 511 $records[$key]->questioncount = 0;
512 }
513 if ($parentkey == 0) {
514 $categorytree[$key] = $records[$key];
515 } else {
516 $records[$parentkey]->children[$key] = $records[$key];
517 }
518 }
519 }
520 return $categorytree;
521 }
522
bc649d80 523 /**
524 * Sets the viable parents
525 *
526 * Viable parents are any except for the category itself, or any of it's descendants
527 * The parentstrings parameter is passed by reference and changed by this function.
528 *
529 * @param array parentstrings a list of parentstrings
530 * @param object category
531 */
516cf3eb 532 function set_viable_parents(&$parentstrings, $category) {
533
534 unset($parentstrings[$category->id]);
535 if (isset($category->children)) {
536 foreach ($category->children as $child) {
537 $this->set_viable_parents($parentstrings, $child);
538 }
539 }
540 }
541
bc649d80 542 /**
543 * Gets question categories
544 *
545 * @param int parent - if given, restrict records to those with this parent id.
546 * @param string sort - [[sortfield [,sortfield]] {ASC|DESC}]
547 * @return array categories
548 */
dc1f00de 549 function get_question_categories($parent=null, $sort="sortorder ASC") {
516cf3eb 550
551 if (is_null($parent)) {
dc1f00de 552 $categories = get_records('question_categories', 'course', "{$this->course->id}", $sort);
516cf3eb 553 } else {
554 $select = "parent = '$parent' AND course = '{$this->course->id}'";
dc1f00de 555 $categories = get_records_select('question_categories', $select, $sort);
516cf3eb 556 }
557 return $categories;
558 }
559
bc649d80 560 /**
561 * Deletes an existing question category
562 *
563 * @param int deletecat id of category to delete
564 * @param int destcategoryid id of category which will inherit the orphans of deletecat
565 */
516cf3eb 566 function delete_category($deletecat, $destcategoryid = null) {
567 global $USER;
568
dc1f00de 569 if (!$category = get_record("question_categories", "id", $deletecat)) { // security
516cf3eb 570 error("No such category $deletecat!", "category.php?id={$this->course->id}");
571 }
572
573 if (!is_null($destcategoryid)) { // Need to move some questions before deleting the category
dc1f00de 574 if (!$category2 = get_record("question_categories", "id", $destcategoryid)) { // security
516cf3eb 575 error("No such category $destcategoryid!", "category.php?id={$this->course->id}");
576 }
4abc23b2 577 if (! set_field('question', 'category', $destcategoryid, 'category', $deletecat)) {
516cf3eb 578 error("Error while moving questions from category '$category->name' to '$category2->name'", "category.php?id={$this->course->id}");
579 }
580
581 } else {
582 // todo: delete any hidden questions that are not actually in use any more
4f48fb42 583 if ($count = count_records("question", "category", $category->id)) {
4abc23b2 584 $vars = new stdClass;
516cf3eb 585 $vars->name = $category->name;
586 $vars->count = $count;
587 print_simple_box(get_string("categorymove", "quiz", $vars), "center");
588 $this->initialize();
589 $categorystrings = $this->categorystrings;
590 unset ($categorystrings[$category->id]);
591 echo "<p><div align=\"center\"><form action=\"category.php\" method=\"get\">";
592 echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
593 echo "<input type=\"hidden\" name=\"id\" value=\"{$this->course->id}\" />";
594 echo "<input type=\"hidden\" name=\"delete\" value=\"$category->id\" />";
595 choose_from_menu($categorystrings, "confirm", "", "");
596 echo "<input type=\"submit\" value=\"". get_string("categorymoveto", "quiz") . "\" />";
597 echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->str->cancel}\" />";
598 echo "</form></div></p>";
599 print_footer($this->course);
600 exit;
601 }
602 }
516cf3eb 603
604 /// Send the children categories to live with their grandparent
dc1f00de 605 if ($childcats = get_records("question_categories", "parent", $category->id)) {
516cf3eb 606 foreach ($childcats as $childcat) {
dc1f00de 607 if (! set_field("question_categories", "parent", $category->parent, "id", $childcat->id)) {
516cf3eb 608 error("Could not update a child category!", "category.php?id={$this->course->id}");
609 }
610 }
611 }
612
613 /// Finally delete the category itself
dc1f00de 614 if (delete_records("question_categories", "id", $category->id)) {
bc649d80 615 notify(get_string("categorydeleted", "quiz", $category->name), 'notifysuccess');
516cf3eb 616 }
617 }
618
bc649d80 619 /**
620 * Moves a category up or down in the display order
621 *
622 * @param string direction up|down
623 * @param int categoryid id of category to move
624 */
516cf3eb 625 function move_category_up_down ($direction, $categoryid) {
626 /// Move a category up or down
627 $swapcategory = NULL;
628 $movecategory = NULL;
629
630 if ($direction == 'up') {
dc1f00de 631 if ($movecategory = get_record("question_categories", "id", $categoryid)) {
632 $categories = $this->get_question_categories("$movecategory->parent", 'parent, sortorder, name');
516cf3eb 633
634 foreach ($categories as $category) {
635 if ($category->id == $movecategory->id) {
636 break;
637 }
638 $swapcategory = $category;
639 }
640 }
641 }
642 if ($direction == 'down') {
dc1f00de 643 if ($movecategory = get_record("question_categories", "id", $categoryid)) {
644 $categories = $this->get_question_categories("$movecategory->parent", 'parent, sortorder, name');
516cf3eb 645 $choosenext = false;
646 foreach ($categories as $category) {
647 if ($choosenext) {
648 $swapcategory = $category;
649 break;
650 }
651 if ($category->id == $movecategory->id) {
652 $choosenext = true;
653 }
654 }
655 }
656 }
657 if ($swapcategory and $movecategory) { // Renumber everything for robustness
658 $count=0;
659 foreach ($categories as $category) {
660 $count++;
661 if ($category->id == $swapcategory->id) {
662 $category = $movecategory;
663 } else if ($category->id == $movecategory->id) {
664 $category = $swapcategory;
665 }
dc1f00de 666 if (! set_field("question_categories", "sortorder", $count, "id", $category->id)) {
516cf3eb 667 notify("Could not update that category!");
668 }
669 }
670 }
671 }
672
bc649d80 673 /**
674 * Changes the parent of a category
675 *
676 * @param int categoryid
677 * @param int parentid
678 */
516cf3eb 679 function move_category($categoryid, $parentid) {
680 /// Move a category to a new parent
681
dc1f00de 682 if ($tempcat = get_record("question_categories", "id", $categoryid)) {
516cf3eb 683 if ($tempcat->parent != $parentid) {
dc1f00de 684 if (! set_field("question_categories", "parent", $parentid, "id", $tempcat->id)) {
516cf3eb 685 notify("Could not update that category!");
686 }
687 }
688 }
689 }
690
bc649d80 691 /**
692 * Changes the published status of a category
693 *
694 * @param boolean publish
695 * @param int categoryid
696 */
516cf3eb 697 function publish_category($publish, $categoryid) {
698 /// Hide or publish a category
699
700 $publish = ($publish == false) ? 0 : 1;
dc1f00de 701 $tempcat = get_record("question_categories", "id", $categoryid);
516cf3eb 702 if ($tempcat) {
dc1f00de 703 if (! set_field("question_categories", "publish", $publish, "id", $tempcat->id)) {
516cf3eb 704 notify("Could not update that category!");
705 }
706 }
707 }
708
bc649d80 709 /**
710 * Creates a new category with given params
711 *
712 * @param int $newparent id of the parent category
713 * @param string $newcategory the name for the new category
714 * @param string $newinfo the info field for the new category
715 * @param int $newpublish whether to publish the category
716 * @param int $newcourse the id of the associated course
717 */
516cf3eb 718 function add_category($newparent, $newcategory, $newinfo, $newpublish, $newcourse) {
bc649d80 719 if (empty($newcategory)) {
720 notify(get_string('categorynamecantbeblank', 'quiz'), 'notifyproblem');
721 return false;
722 }
516cf3eb 723
724 if ($newparent) {
725 // first check that the parent category is in the correct course
dc1f00de 726 if(!(get_field('question_categories', 'course', 'id', $newparent) == $newcourse)) {
516cf3eb 727 return false;
728 }
729 }
730
731 $cat = NULL;
732 $cat->parent = $newparent;
733 $cat->name = $newcategory;
734 $cat->info = $newinfo;
735 $cat->publish = $newpublish;
736 $cat->course = $newcourse;
737 $cat->sortorder = 999;
738 $cat->stamp = make_unique_id_code();
dc1f00de 739 if (!insert_record("question_categories", $cat)) {
f5565b69 740 error("Could not insert the new question category '$newcategory'", "category.php?id={$newcourse}");
516cf3eb 741 } else {
bc649d80 742 notify(get_string("categoryadded", "quiz", $newcategory), 'notifysuccess');
516cf3eb 743 }
516cf3eb 744 }
745
bc649d80 746 /**
747 * Updates an existing category with given params
748 *
749 * @param int updateid
750 * @param int updateparent
751 * @param string updatename
752 * @param string updateinfo
753 * @param int updatepublish
754 * @param int courseid the id of the associated course
755 */
516cf3eb 756 function update_category($updateid, $updateparent, $updatename, $updateinfo, $updatepublish, $courseid) {
bc649d80 757 if (empty($updatename)) {
758 notify(get_string('categorynamecantbeblank', 'quiz'), 'notifyproblem');
759 return false;
760 }
516cf3eb 761
762 $cat = NULL;
763 $cat->id = $updateid;
764 $cat->parent = $updateparent;
765 $cat->name = $updatename;
766 $cat->info = $updateinfo;
767 $cat->publish = $updatepublish;
dc1f00de 768 if (!update_record("question_categories", $cat)) {
516cf3eb 769 error("Could not update the category '$updatename'", "category.php?id={$courseid}");
770 } else {
bc649d80 771 notify(get_string("categoryupdated", 'quiz'), 'notifysuccess');
516cf3eb 772 }
773 }
516cf3eb 774}
775
776?>