moodle_page: MDL-12212 reimplement user_is_editing, deprecate isediting
[moodle.git] / course / category.php
1 <?php // $Id$
2       // Displays the top level category or all courses
3       // In editing mode, allows the admin to edit a category,
4       // and rearrange courses
6     require_once("../config.php");
7     require_once("lib.php");
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
12     $categoryedit = optional_param('categoryedit', -1, PARAM_BOOL);
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);
20     if ($CFG->forcelogin) {
21         require_login();
22     }
24     if (!$site = get_site()) {
25         print_error('siteisnotdefined', 'debug');
26     }
28     if (empty($id)) {
29         print_error("unknowcategory");
30     }
32     $PAGE->set_category_by_id($id);
33     $context = $PAGE->context;
34     $category = $PAGE->category;
36     if (!$category->visible) {
37         require_capability('moodle/category:viewhiddencategories', $context);
38     }
40     if (update_category_button($category->id)) {
41         if ($categoryedit !== -1) {
42             $USER->editing = $categoryedit;
43         }
44         $editingon = $PAGE->user_is_editing();
45         $navbaritem = update_category_button($category->id); // Must call this again after updating the state.
46     } else {
47         $navbaritem = print_course_search('', true, 'navbar');
48         $editingon = false;
49     }
51     // Process any category actions.
52     if (has_capability('moodle/category:manage', $context)) {
53         /// Resort the category if requested
54         if ($resort and confirm_sesskey()) {
55             if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
56                 $i = 1;
57                 foreach ($courses as $course) {
58                     $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id));
59                     $i++;
60                 }
61                 fix_course_sortorder(); // should not be needed
62             }
63         }
64     }
66     if(!empty($CFG->allowcategorythemes) && isset($category->theme)) {
67         // specifying theme here saves us some dbqs
68         theme_setup($category->theme);
69     }
71 /// Print headings
72     $numcategories = $DB->count_records('course_categories');
74     $stradministration = get_string('administration');
75     $strcategories = get_string('categories');
76     $strcategory = get_string('category');
77     $strcourses = get_string('courses');
79     $navlinks = array();
80     $navlinks[] = array('name' => $strcategories, 'link' => 'index.php', 'type' => 'misc');
81     $navlinks[] = array('name' => format_string($category->name), 'link' => null, 'type' => 'misc');
82     $navigation = build_navigation($navlinks);
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');
88         admin_externalpage_setup('coursemgmt', $navbaritem, array('id' => $id,
89                 'page' => $page, 'perpage' => $perpage), $CFG->wwwroot . '/course/category.php');
90         admin_externalpage_print_header();
91     } else {
92         print_header("$site->shortname: $category->name", "$site->fullname: $strcourses", $navigation, '', '', true, $navbaritem);
93     }
95 /// Print link to roles
96     if (has_capability('moodle/role:assign', $context)) {
97         echo '<div class="rolelink"><a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
98          $context->id.'">'.get_string('assignroles','role').'</a></div>';
99     }
101 /// Print the category selector
102     $displaylist = array();
103     $notused = array();
104     make_categories_list($displaylist, $notused);
106     echo '<div class="categorypicker">';
107     popup_form('category.php?id=', $displaylist, 'switchcategory', $category->id, '', '', '', false, 'self', $strcategories.':');
108     echo '</div>';
110 /// Print current category description
111     if (!$editingon && $category->description) {
112         print_box_start();
113         echo format_text($category->description); // for multilang filter
114         print_box_end();
115     }
117 /// Process any course actions.
118     if ($editingon) {
119     /// Move a specified course to a new category
120         if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) {   // Some courses are being moved
121             // user must have category update in both cats to perform this
122             require_capability('moodle/category:manage', $context);
123             require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto));
125             if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) {
126                 print_error('cannotfindcategory', '', '', $data->moveto);
127             }
129             $courses = array();
130             foreach ($data as $key => $value) {
131                 if (preg_match('/^c\d+$/', $key)) {
132                     array_push($courses, substr($key, 1));
133                 }
134             }
135             move_courses($courses, $data->moveto);
136         }
138     /// Hide or show a course
139         if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
140             require_capability('moodle/course:visibility', $context);
141             if (!empty($hide)) {
142                 $course = $DB->get_record('course', array('id' => $hide));
143                 $visible = 0;
144             } else {
145                 $course = $DB->get_record('course', array('id' => $show));
146                 $visible = 1;
147             }
148             if ($course) {
149                 if (!$DB->set_field('course', 'visible', $visible, array('id' => $course->id))) {
150                     print_error('errorupdatingcoursevisibility');
151                 }
152             }
153         }
156     /// Move a course up or down
157         if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
158             require_capability('moodle/category:manage', $context);
160             // Ensure the course order has continuous ordering
161             fix_course_sortorder();
162             $swapcourse = NULL;
164             if (!empty($moveup)) {
165                 if ($movecourse = $DB->get_record('course', array('id' => $moveup))) {
166                     $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1));
167                 }
168             } else {
169                 if ($movecourse = $DB->get_record('course', array('id' => $movedown))) {
170                     $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1));
171                 }
172             }
173             if ($swapcourse and $movecourse) {
174                 $DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id));
175                 $DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id));
176             }
177         }
179     } // End of editing stuff
181     if ($editingon && has_capability('moodle/category:manage', $context)) {
182         echo '<div class="buttons">';
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');
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');
192         echo '</div>';
193     }
195 /// Print out all the sub-categories
196     if ($subcategories = $DB->get_records('course_categories', array('parent' => $category->id), 'sortorder ASC')) {
197         $firstentry = true;
198         foreach ($subcategories as $subcategory) {
199             if ($subcategory->visible || has_capability('moodle/category:viewhiddencategories', $context)) {
200                 $subcategorieswereshown = true;
201                 if ($firstentry) {
202                     echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter">';
203                     echo '<tr><th scope="col">'.get_string('subcategories').'</th></tr>';
204                     echo '<tr><td style="white-space: nowrap">';
205                     $firstentry = false;
206                 }
207                 $catlinkcss = $subcategory->visible ? '' : ' class="dimmed" ';
208                 echo '<a '.$catlinkcss.' href="category.php?id='.$subcategory->id.'">'.
209                      format_string($subcategory->name).'</a><br />';
210             }
211         }
212         if (!$firstentry) {
213             echo '</td></tr></table>';
214             echo '<br />';
215         }
216     }
218 /// Print out all the courses
219     $courses = get_courses_page($category->id, 'c.sortorder ASC',
220             'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible,c.guest,c.password',
221             $totalcount, $page*$perpage, $perpage);
222     $numcourses = count($courses);
224     if (!$courses) {
225         if (empty($subcategorieswereshown)) {
226             print_heading(get_string("nocoursesyet"));
227         }
229     } else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) {
230         print_box_start('courseboxes');
231         print_courses($category);
232         print_box_end();
234     } else {
235         print_paging_bar($totalcount, $page, $perpage, "category.php?id=$category->id&amp;perpage=$perpage&amp;");
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');
255         echo '<form id="movecourses" action="category.php" method="post"><div>';
256         echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
257         echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter"><tr>';
258         echo '<th class="header" scope="col">'.$strcourses.'</th>';
259         if ($editingon) {
260             echo '<th class="header" scope="col">'.$stredit.'</th>';
261             echo '<th class="header" scope="col">'.$strselect.'</th>';
262         } else {
263             echo '<th class="header" scope="col">&nbsp;</th>';
264         }
265         echo '</tr>';
268         $count = 0;
269         $abletomovecourses = false;  // for now
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);
275             if ($perpage > 0) {
276                 $atlastpage = (($page + 1) == ceil($totalcount / $perpage));
277             } else {
278                 $atlastpage = true;
279             }
280         } else {
281             $atfirstpage = true;
282             $atlastpage = true;
283         }
285         $spacer = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
286         foreach ($courses as $acourse) {
287             if (isset($acourse->context)) {
288                 $coursecontext = $acourse->context;
289             } else {
290                 $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id);
291             }
293             $count++;
294             $up = ($count > 1 || !$atfirstpage);
295             $down = ($count < $numcourses || !$atlastpage);
297             $linkcss = $acourse->visible ? '' : ' class="dimmed" ';
298             echo '<tr>';
299             echo '<td><a '.$linkcss.' href="view.php?id='.$acourse->id.'">'. format_string($acourse->fullname) .'</a></td>';
300             if ($editingon) {
301                 echo '<td>';
302                 if (has_capability('moodle/course:update', $coursecontext)) {
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                 }
309                 // role assignment link
310                 if (has_capability('moodle/role:assign', $coursecontext)) {
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;
315                 }
317                 if (can_delete_course($acourse->id)) {
318                     echo '<a title="'.$strdelete.'" href="delete.php?id='.$acourse->id.'">'.
319                             '<img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" /></a> ';
320                 } else {
321                     echo $spacer;
322                 }
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)) {
326                     if (!empty($acourse->visible)) {
327                         echo '<a title="'.$strhide.'" href="category.php?id='.$category->id.'&amp;page='.$page.
328                             '&amp;perpage='.$perpage.'&amp;hide='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
329                             '<img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$strhide.'" /></a> ';
330                     } else {
331                         echo '<a title="'.$strshow.'" href="category.php?id='.$category->id.'&amp;page='.$page.
332                             '&amp;perpage='.$perpage.'&amp;show='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
333                             '<img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" /></a> ';
334                     }
335                 } else {
336                     echo $spacer;
337                 }
339                 if (has_capability('moodle/site:backup', $coursecontext)) {
340                     echo '<a title="'.$strbackup.'" href="../backup/backup.php?id='.$acourse->id.'">'.
341                             '<img src="'.$CFG->pixpath.'/t/backup.gif" class="iconsmall" alt="'.$strbackup.'" /></a> ';
342                 } else {
343                     echo $spacer;
344                 }
346                 if (has_capability('moodle/site:restore', $coursecontext)) {
347                     echo '<a title="'.$strrestore.'" href="../files/index.php?id='.$acourse->id.
348                          '&amp;wdir=/backupdata">'.
349                          '<img src="'.$CFG->pixpath.'/t/restore.gif" class="iconsmall" alt="'.$strrestore.'" /></a> ';
350                 } else {
351                     echo $spacer;
352                 }
354                 if (has_capability('moodle/category:manage', $context)) {
355                     if ($up) {
356                         echo '<a title="'.$strmoveup.'" href="category.php?id='.$category->id.'&amp;page='.$page.
357                              '&amp;perpage='.$perpage.'&amp;moveup='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
358                              '<img src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$strmoveup.'" /></a> ';
359                     } else {
360                         echo $spacer;
361                     }
363                     if ($down) {
364                         echo '<a title="'.$strmovedown.'" href="category.php?id='.$category->id.'&amp;page='.$page.
365                              '&amp;perpage='.$perpage.'&amp;movedown='.$acourse->id.'&amp;sesskey='.sesskey().'">'.
366                              '<img src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$strmovedown.'" /></a> ';
367                     } else {
368                         echo $spacer;
369                     }
370                     $abletomovecourses = true;
371                 } else {
372                     echo $spacer, $spacer;
373                 }
375                 echo '</td>';
376                 echo '<td align="center">';
377                 echo '<input type="checkbox" name="c'.$acourse->id.'" />';
378                 echo '</td>';
379             } else {
380                 echo '<td align="right">';
381                 if (!empty($acourse->guest)) {
382                     echo '<a href="view.php?id='.$acourse->id.'"><img title="'.
383                          $strallowguests.'" class="icon" src="'.
384                          $CFG->pixpath.'/i/guest.gif" alt="'.$strallowguests.'" /></a>';
385                 }
386                 if (!empty($acourse->password)) {
387                     echo '<a href="view.php?id='.$acourse->id.'"><img title="'.
388                          $strrequireskey.'" class="icon" src="'.
389                          $CFG->pixpath.'/i/key.gif" alt="'.$strrequireskey.'" /></a>';
390                 }
391                 if (!empty($acourse->summary)) {
392                     link_to_popup_window ("/course/info.php?id=$acourse->id", "courseinfo",
393                                           '<img alt="'.get_string('info').'" class="icon" src="'.$CFG->pixpath.'/i/info.gif" />',
394                                            400, 500, $strsummary);
395                 }
396                 echo "</td>";
397             }
398             echo "</tr>";
399         }
401         if ($abletomovecourses) {
402             $movetocategories = array();
403             $notused = array();
404             make_categories_list($movetocategories, $notused, 'moodle/category:manage');
405             $movetocategories[$category->id] = get_string('moveselectedcoursesto');
406             echo '<tr><td colspan="3" align="right">';
407             choose_from_menu($movetocategories, 'moveto', $category->id, '', "javascript:submitFormById('movecourses')");
408             echo '<input type="hidden" name="id" value="'.$category->id.'" />';
409             echo '</td></tr>';
410         }
412         echo '</table>';
413         echo '</div></form>';
414         echo '<br />';
415     }
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
420         unset($options);
421         $options['id'] = $category->id;
422         $options['resort'] = 'name';
423         $options['sesskey'] = sesskey();
424         print_single_button('category.php', $options, get_string('resortcoursesbyname'), 'get');
425     }
427     if (has_capability('moodle/course:create', $context)) {
428     /// Print button to create a new course
429         unset($options);
430         $options['category'] = $category->id;
431         print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
432     }
434     if (!empty($CFG->enablecourserequests) && $category->id == $CFG->enablecourserequests) {
435         print_course_request_buttons(get_context_instance(CONTEXT_SYSTEM));
436     }
437     echo '</div>';
439     print_course_search();
441     print_footer();
443 ?>