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