moodle_page: MDL-12212 reimplement user_is_editing, deprecate isediting
[moodle.git] / course / category.php
CommitLineData
24f2b65a 1<?php // $Id$
d2b6ba70 2 // Displays the top level category or all courses
daa27ce4 3 // In editing mode, allows the admin to edit a category,
d2b6ba70 4 // and rearrange courses
c2cb4545 5
4f006bc1 6 require_once("../config.php");
7 require_once("lib.php");
c2cb4545 8
8ed5dd63 9 $id = required_param('id', PARAM_INT); // Category id
10 $page = optional_param('page', 0, PARAM_INT); // which page to show
11 $perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page
1be4d00d 12 $categoryedit = optional_param('categoryedit', -1, PARAM_BOOL);
8ed5dd63 13 $hide = optional_param('hide', 0, PARAM_INT);
14 $show = optional_param('show', 0, PARAM_INT);
15 $moveup = optional_param('moveup', 0, PARAM_INT);
16 $movedown = optional_param('movedown', 0, PARAM_INT);
17 $moveto = optional_param('moveto', 0, PARAM_INT);
18 $resort = optional_param('resort', 0, PARAM_BOOL);
c2cb4545 19
10ed581c 20 if ($CFG->forcelogin) {
21 require_login();
22 }
23
c2cb4545 24 if (!$site = get_site()) {
8ed5dd63 25 print_error('siteisnotdefined', 'debug');
c2cb4545 26 }
e295df44 27
10ed581c 28 if (empty($id)) {
ba6018a9 29 print_error("unknowcategory");
10ed581c 30 }
e295df44 31
948203a5 32 $PAGE->set_category_by_id($id);
33 $context = $PAGE->context;
34 $category = $PAGE->category;
4f006bc1 35
8ed5dd63 36 if (!$category->visible) {
37 require_capability('moodle/category:viewhiddencategories', $context);
38 }
f26cfa22 39
8ed5dd63 40 if (update_category_button($category->id)) {
1be4d00d 41 if ($categoryedit !== -1) {
830dd6e9 42 $USER->editing = $categoryedit;
d2b6ba70 43 }
830dd6e9 44 $editingon = $PAGE->user_is_editing();
8ed5dd63 45 $navbaritem = update_category_button($category->id); // Must call this again after updating the state.
d2b6ba70 46 } else {
8ed5dd63 47 $navbaritem = print_course_search('', true, 'navbar');
48 $editingon = false;
d2b6ba70 49 }
c2cb4545 50
8ed5dd63 51 // Process any category actions.
52 if (has_capability('moodle/category:manage', $context)) {
52a554db 53 /// Resort the category if requested
de9924ae 54 if ($resort and confirm_sesskey()) {
ba87a4da 55 if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
0cbe8111 56 $i = 1;
6bc502cc 57 foreach ($courses as $course) {
0cbe8111 58 $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id));
59 $i++;
6bc502cc 60 }
0cbe8111 61 fix_course_sortorder(); // should not be needed
6bc502cc 62 }
52a554db 63 }
49d3bab8 64 }
65
8ed5dd63 66 if(!empty($CFG->allowcategorythemes) && isset($category->theme)) {
67 // specifying theme here saves us some dbqs
68 theme_setup($category->theme);
f4eb549f 69 }
70
d2b6ba70 71/// Print headings
8ed5dd63 72 $numcategories = $DB->count_records('course_categories');
d2b6ba70 73
8ed5dd63 74 $stradministration = get_string('administration');
75 $strcategories = get_string('categories');
76 $strcategory = get_string('category');
77 $strcourses = get_string('courses');
d2b6ba70 78
e295df44 79 $navlinks = array();
80 $navlinks[] = array('name' => $strcategories, 'link' => 'index.php', 'type' => 'misc');
f26cfa22 81 $navlinks[] = array('name' => format_string($category->name), 'link' => null, 'type' => 'misc');
e295df44 82 $navigation = build_navigation($navlinks);
83
8ed5dd63 84 if ($editingon && update_category_button()) {
85 // Integrate into the admin tree only if the user can edit categories at the top level,
86 // otherwise the admin block does not appear to this user, and you get an error.
87 require_once($CFG->libdir.'/adminlib.php');
92f00846 88 admin_externalpage_setup('coursemgmt', $navbaritem, array('id' => $id,
89 'page' => $page, 'perpage' => $perpage), $CFG->wwwroot . '/course/category.php');
8ed5dd63 90 admin_externalpage_print_header();
d2b6ba70 91 } else {
8ed5dd63 92 print_header("$site->shortname: $category->name", "$site->fullname: $strcourses", $navigation, '', '', true, $navbaritem);
d2b6ba70 93 }
94
dc558690 95/// Print link to roles
e295df44 96 if (has_capability('moodle/role:assign', $context)) {
be636898 97 echo '<div class="rolelink"><a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
de51fa56 98 $context->id.'">'.get_string('assignroles','role').'</a></div>';
99 }
c2cb4545 100
8ed5dd63 101/// Print the category selector
c2cb4545 102 $displaylist = array();
8ed5dd63 103 $notused = array();
104 make_categories_list($displaylist, $notused);
daa27ce4 105
fcf9577a 106 echo '<div class="categorypicker">';
107 popup_form('category.php?id=', $displaylist, 'switchcategory', $category->id, '', '', '', false, 'self', $strcategories.':');
108 echo '</div>';
c2cb4545 109
ca5d523b 110/// Print current category description
8ed5dd63 111 if (!$editingon && $category->description) {
ca5d523b 112 print_box_start();
f26cfa22 113 echo format_text($category->description); // for multilang filter
ca5d523b 114 print_box_end();
115 }
c2cb4545 116
8ed5dd63 117/// Process any course actions.
118 if ($editingon) {
daa27ce4 119 /// Move a specified course to a new category
294ce987 120 if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) { // Some courses are being moved
115a622d 121 // user must have category update in both cats to perform this
8ed5dd63 122 require_capability('moodle/category:manage', $context);
123 require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto));
e295df44 124
8ed5dd63 125 if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) {
126 print_error('cannotfindcategory', '', '', $data->moveto);
f2bb0045 127 }
128
e295df44 129 $courses = array();
8ed5dd63 130 foreach ($data as $key => $value) {
861efb19 131 if (preg_match('/^c\d+$/', $key)) {
132 array_push($courses, substr($key, 1));
d2b6ba70 133 }
e295df44 134 }
861efb19 135 move_courses($courses, $data->moveto);
c2cb4545 136 }
c2cb4545 137
daa27ce4 138 /// Hide or show a course
7168423c 139 if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
115a622d 140 require_capability('moodle/course:visibility', $context);
7168423c 141 if (!empty($hide)) {
8ed5dd63 142 $course = $DB->get_record('course', array('id' => $hide));
d2b6ba70 143 $visible = 0;
144 } else {
8ed5dd63 145 $course = $DB->get_record('course', array('id' => $show));
d2b6ba70 146 $visible = 1;
147 }
148 if ($course) {
8ed5dd63 149 if (!$DB->set_field('course', 'visible', $visible, array('id' => $course->id))) {
150 print_error('errorupdatingcoursevisibility');
d2b6ba70 151 }
152 }
153 }
c2cb4545 154
c2cb4545 155
d2b6ba70 156 /// Move a course up or down
7168423c 157 if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
8ed5dd63 158 require_capability('moodle/category:manage', $context);
daa27ce4 159
8ed5dd63 160 // Ensure the course order has continuous ordering
0cbe8111 161 fix_course_sortorder();
162 $swapcourse = NULL;
daa27ce4 163
7168423c 164 if (!empty($moveup)) {
8ed5dd63 165 if ($movecourse = $DB->get_record('course', array('id' => $moveup))) {
166 $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1));
0cbe8111 167 }
ba87a4da 168 } else {
8ed5dd63 169 if ($movecourse = $DB->get_record('course', array('id' => $movedown))) {
170 $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1));
d2b6ba70 171 }
c2cb4545 172 }
0cbe8111 173 if ($swapcourse and $movecourse) {
8ed5dd63 174 $DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id));
175 $DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id));
0cbe8111 176 }
ba87a4da 177 }
d2b6ba70 178
179 } // End of editing stuff
c2cb4545 180
8ed5dd63 181 if ($editingon && has_capability('moodle/category:manage', $context)) {
182 echo '<div class="buttons">';
09deab06 183
8ed5dd63 184 // Print button to update this category
185 $options = array('id' => $category->id);
186 print_single_button($CFG->wwwroot.'/course/editcategory.php', $options, get_string('editcategorythis'), 'get');
187
188 // Print button for creating new categories
189 $options = array('parent' => $category->id);
190 print_single_button($CFG->wwwroot.'/course/editcategory.php', $options, get_string('addsubcategory'), 'get');
09deab06 191
09deab06 192 echo '</div>';
193 }
194
8210692d 195/// Print out all the sub-categories
8ed5dd63 196 if ($subcategories = $DB->get_records('course_categories', array('parent' => $category->id), 'sortorder ASC')) {
92c26858 197 $firstentry = true;
8210692d 198 foreach ($subcategories as $subcategory) {
8ed5dd63 199 if ($subcategory->visible || has_capability('moodle/category:viewhiddencategories', $context)) {
15cf5d21 200 $subcategorieswereshown = true;
92c26858 201 if ($firstentry) {
4e957c86 202 echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter">';
54926e78 203 echo '<tr><th scope="col">'.get_string('subcategories').'</th></tr>';
fbe31d22 204 echo '<tr><td style="white-space: nowrap">';
92c26858 205 $firstentry = false;
206 }
8ed5dd63 207 $catlinkcss = $subcategory->visible ? '' : ' class="dimmed" ';
e5e81e78 208 echo '<a '.$catlinkcss.' href="category.php?id='.$subcategory->id.'">'.
6ba65fa0 209 format_string($subcategory->name).'</a><br />';
92c26858 210 }
211 }
212 if (!$firstentry) {
8ed5dd63 213 echo '</td></tr></table>';
214 echo '<br />';
8210692d 215 }
8210692d 216 }
daa27ce4 217
d2b6ba70 218/// Print out all the courses
daa27ce4 219 $courses = get_courses_page($category->id, 'c.sortorder ASC',
8ed5dd63 220 'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible,c.guest,c.password',
221 $totalcount, $page*$perpage, $perpage);
f1c1b17a 222 $numcourses = count($courses);
c2cb4545 223
e646a256 224 if (!$courses) {
15cf5d21 225 if (empty($subcategorieswereshown)) {
226 print_heading(get_string("nocoursesyet"));
227 }
c2cb4545 228
8ed5dd63 229 } else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) {
6463b3de 230 print_box_start('courseboxes');
35d0244a 231 print_courses($category);
6463b3de 232 print_box_end();
c2cb4545 233
daa27ce4 234 } else {
37304884 235 print_paging_bar($totalcount, $page, $perpage, "category.php?id=$category->id&amp;perpage=$perpage&amp;");
8ef9cb56 236
8ed5dd63 237 $strcourses = get_string('courses');
238 $strselect = get_string('select');
239 $stredit = get_string('edit');
240 $strdelete = get_string('delete');
241 $strbackup = get_string('backup');
242 $strrestore = get_string('restore');
243 $strmoveup = get_string('moveup');
244 $strmovedown = get_string('movedown');
245 $strupdate = get_string('update');
246 $strhide = get_string('hide');
247 $strshow = get_string('show');
248 $strsummary = get_string('summary');
249 $strsettings = get_string('settings');
250 $strassignteachers = get_string('assignteachers');
251 $strallowguests = get_string('allowguests');
252 $strrequireskey = get_string('requireskey');
c2cb4545 253
d2b6ba70 254
be636898 255 echo '<form id="movecourses" action="category.php" method="post"><div>';
d8807190 256 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
be636898 257 echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter"><tr>';
258 echo '<th class="header" scope="col">'.$strcourses.'</th>';
8ed5dd63 259 if ($editingon) {
be636898 260 echo '<th class="header" scope="col">'.$stredit.'</th>';
8ed5dd63 261 echo '<th class="header" scope="col">'.$strselect.'</th>';
3d95bdb7 262 } else {
be636898 263 echo '<th class="header" scope="col">&nbsp;</th>';
d2b6ba70 264 }
d8807190 265 echo '</tr>';
d2b6ba70 266
c2cb4545 267
c2cb4545 268 $count = 0;
f2bb0045 269 $abletomovecourses = false; // for now
c2cb4545 270
c851eb94 271 // Checking if we are at the first or at the last page, to allow courses to
272 // be moved up and down beyond the paging border
273 if ($totalcount > $perpage) {
274 $atfirstpage = ($page == 0);
7b0d5cd5 275 if ($perpage > 0) {
276 $atlastpage = (($page + 1) == ceil($totalcount / $perpage));
277 } else {
278 $atlastpage = true;
279 }
c851eb94 280 } else {
281 $atfirstpage = true;
282 $atlastpage = true;
283 }
284
8ed5dd63 285 $spacer = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
e081f299 286 foreach ($courses as $acourse) {
679b6179 287 if (isset($acourse->context)) {
288 $coursecontext = $acourse->context;
289 } else {
290 $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id);
291 }
e295df44 292
c2cb4545 293 $count++;
c851eb94 294 $up = ($count > 1 || !$atfirstpage);
295 $down = ($count < $numcourses || !$atlastpage);
c2cb4545 296
8ed5dd63 297 $linkcss = $acourse->visible ? '' : ' class="dimmed" ';
d8807190 298 echo '<tr>';
6ba65fa0 299 echo '<td><a '.$linkcss.' href="view.php?id='.$acourse->id.'">'. format_string($acourse->fullname) .'</a></td>';
8ed5dd63 300 if ($editingon) {
301 echo '<td>';
4827a1d1 302 if (has_capability('moodle/course:update', $coursecontext)) {
8ed5dd63 303 echo '<a title="'.$strsettings.'" href="'.$CFG->wwwroot.'/course/edit.php?id='.$acourse->id.'">'.
304 '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" /></a> ';
305 } else {
306 echo $spacer;
307 }
e295df44 308
309 // role assignment link
310 if (has_capability('moodle/role:assign', $coursecontext)) {
8ed5dd63 311 echo '<a title="'.get_string('assignroles', 'role').'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$coursecontext->id.'">'.
312 '<img src="'.$CFG->pixpath.'/i/roles.gif" class="iconsmall" alt="'.get_string('assignroles', 'role').'" /></a> ';
313 } else {
314 echo $spacer;
e295df44 315 }
316
2585a68d 317 if (can_delete_course($acourse->id)) {
555b75f4 318 echo '<a title="'.$strdelete.'" href="delete.php?id='.$acourse->id.'">'.
0d905d9f 319 '<img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" /></a> ';
8ed5dd63 320 } else {
321 echo $spacer;
555b75f4 322 }
bbbf2d40 323
cbc943f7 324 // MDL-8885, users with no capability to view hidden courses, should not be able to lock themselves out
325 if (has_capability('moodle/course:visibility', $coursecontext) && has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
555b75f4 326 if (!empty($acourse->visible)) {
327 echo '<a title="'.$strhide.'" href="category.php?id='.$category->id.'&amp;page='.$page.
d4a1fcaf 328 '&amp;perpage='.$perpage.'&amp;hide='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
0d905d9f 329 '<img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$strhide.'" /></a> ';
555b75f4 330 } else {
331 echo '<a title="'.$strshow.'" href="category.php?id='.$category->id.'&amp;page='.$page.
d4a1fcaf 332 '&amp;perpage='.$perpage.'&amp;show='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
0d905d9f 333 '<img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" /></a> ';
bbbf2d40 334 }
8ed5dd63 335 } else {
336 echo $spacer;
555b75f4 337 }
bbbf2d40 338
4827a1d1 339 if (has_capability('moodle/site:backup', $coursecontext)) {
555b75f4 340 echo '<a title="'.$strbackup.'" href="../backup/backup.php?id='.$acourse->id.'">'.
0d905d9f 341 '<img src="'.$CFG->pixpath.'/t/backup.gif" class="iconsmall" alt="'.$strbackup.'" /></a> ';
8ed5dd63 342 } else {
343 echo $spacer;
555b75f4 344 }
e295df44 345
4827a1d1 346 if (has_capability('moodle/site:restore', $coursecontext)) {
555b75f4 347 echo '<a title="'.$strrestore.'" href="../files/index.php?id='.$acourse->id.
348 '&amp;wdir=/backupdata">'.
0d905d9f 349 '<img src="'.$CFG->pixpath.'/t/restore.gif" class="iconsmall" alt="'.$strrestore.'" /></a> ';
8ed5dd63 350 } else {
351 echo $spacer;
555b75f4 352 }
daa27ce4 353
8ed5dd63 354 if (has_capability('moodle/category:manage', $context)) {
d2b6ba70 355 if ($up) {
ba87a4da 356 echo '<a title="'.$strmoveup.'" href="category.php?id='.$category->id.'&amp;page='.$page.
d4a1fcaf 357 '&amp;perpage='.$perpage.'&amp;moveup='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
0d905d9f 358 '<img src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$strmoveup.'" /></a> ';
47a5aeef 359 } else {
8ed5dd63 360 echo $spacer;
d2b6ba70 361 }
daa27ce4 362
d2b6ba70 363 if ($down) {
ba87a4da 364 echo '<a title="'.$strmovedown.'" href="category.php?id='.$category->id.'&amp;page='.$page.
d4a1fcaf 365 '&amp;perpage='.$perpage.'&amp;movedown='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
0d905d9f 366 '<img src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$strmovedown.'" /></a> ';
47a5aeef 367 } else {
8ed5dd63 368 echo $spacer;
d2b6ba70 369 }
f2bb0045 370 $abletomovecourses = true;
8ed5dd63 371 } else {
372 echo $spacer, $spacer;
3d95bdb7 373 }
e295df44 374
d8807190 375 echo '</td>';
555b75f4 376 echo '<td align="center">';
377 echo '<input type="checkbox" name="c'.$acourse->id.'" />';
e295df44 378 echo '</td>';
3d95bdb7 379 } else {
d8807190 380 echo '<td align="right">';
0f06e85a 381 if (!empty($acourse->guest)) {
0d905d9f 382 echo '<a href="view.php?id='.$acourse->id.'"><img title="'.
b469b1b4 383 $strallowguests.'" class="icon" src="'.
d7531392 384 $CFG->pixpath.'/i/guest.gif" alt="'.$strallowguests.'" /></a>';
3d95bdb7 385 }
0f06e85a 386 if (!empty($acourse->password)) {
0d905d9f 387 echo '<a href="view.php?id='.$acourse->id.'"><img title="'.
b469b1b4 388 $strrequireskey.'" class="icon" src="'.
344044b2 389 $CFG->pixpath.'/i/key.gif" alt="'.$strrequireskey.'" /></a>';
f1c1b17a 390 }
0f06e85a 391 if (!empty($acourse->summary)) {
daa27ce4 392 link_to_popup_window ("/course/info.php?id=$acourse->id", "courseinfo",
0d905d9f 393 '<img alt="'.get_string('info').'" class="icon" src="'.$CFG->pixpath.'/i/info.gif" />',
f1c1b17a 394 400, 500, $strsummary);
3d95bdb7 395 }
396 echo "</td>";
c2cb4545 397 }
c2cb4545 398 echo "</tr>";
399 }
f2bb0045 400
401 if ($abletomovecourses) {
8ed5dd63 402 $movetocategories = array();
403 $notused = array();
404 make_categories_list($movetocategories, $notused, 'moodle/category:manage');
405 $movetocategories[$category->id] = get_string('moveselectedcoursesto');
d8807190 406 echo '<tr><td colspan="3" align="right">';
8ed5dd63 407 choose_from_menu($movetocategories, 'moveto', $category->id, '', "javascript:submitFormById('movecourses')");
e5e81e78 408 echo '<input type="hidden" name="id" value="'.$category->id.'" />';
d8807190 409 echo '</td></tr>';
f2bb0045 410 }
daa27ce4 411
d8807190 412 echo '</table>';
be636898 413 echo '</div></form>';
d8807190 414 echo '<br />';
c2cb4545 415 }
e295df44 416
8ed5dd63 417 echo '<div class="buttons">';
418 if (has_capability('moodle/category:manage', $context) and $numcourses > 1) {
419 /// Print button to re-sort courses by name
49d3bab8 420 unset($options);
d8807190 421 $options['id'] = $category->id;
422 $options['resort'] = 'name';
4d933beb 423 $options['sesskey'] = sesskey();
d8807190 424 print_single_button('category.php', $options, get_string('resortcoursesbyname'), 'get');
c432fd32 425 }
49d3bab8 426
8ed5dd63 427 if (has_capability('moodle/course:create', $context)) {
428 /// Print button to create a new course
f2bb0045 429 unset($options);
d8807190 430 $options['category'] = $category->id;
431 print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
c432fd32 432 }
77eddcd5 433
434 if (!empty($CFG->enablecourserequests) && $category->id == $CFG->enablecourserequests) {
435 print_course_request_buttons(get_context_instance(CONTEXT_SYSTEM));
436 }
8ed5dd63 437 echo '</div>';
e295df44 438
61240489 439 print_course_search();
e295df44 440
40935142 441 print_footer();
c2cb4545 442
443?>