Commit | Line | Data |
---|---|---|
58b45fd7 | 1 | <?php |
f73cea54 SH |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * Displays the top level category or all courses | |
19 | * In editing mode, allows the admin to edit a category, | |
20 | * and rearrange courses | |
21 | * | |
22 | * @package core | |
23 | * @subpackage course | |
24 | * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} | |
25 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
26 | */ | |
27 | ||
28 | require_once("../config.php"); | |
29 | require_once($CFG->dirroot.'/course/lib.php'); | |
30 | ||
31 | $id = required_param('id', PARAM_INT); // Category id | |
32 | $page = optional_param('page', 0, PARAM_INT); // which page to show | |
33 | $perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page | |
34 | $categoryedit = optional_param('categoryedit', -1, PARAM_BOOL); | |
35 | $hide = optional_param('hide', 0, PARAM_INT); | |
36 | $show = optional_param('show', 0, PARAM_INT); | |
37 | $moveup = optional_param('moveup', 0, PARAM_INT); | |
38 | $movedown = optional_param('movedown', 0, PARAM_INT); | |
39 | $moveto = optional_param('moveto', 0, PARAM_INT); | |
40 | $resort = optional_param('resort', 0, PARAM_BOOL); | |
41 | $sesskey = optional_param('sesskey', '', PARAM_RAW); | |
42 | ||
43 | if (empty($id)) { | |
44 | print_error("unknowcategory"); | |
45 | } | |
46 | ||
47 | $PAGE->set_category_by_id($id); | |
48 | $PAGE->set_url(new moodle_url('/course/category.php', array('id' => $id))); | |
49 | // This is sure to be the category context | |
50 | $context = $PAGE->context; | |
51 | // And the object has been loaded for us no need for another DB call | |
52 | $category = $PAGE->category; | |
53 | ||
54 | $canedit = can_edit_in_category($category->id); | |
55 | if ($canedit) { | |
56 | if ($categoryedit !== -1) { | |
57 | $USER->editing = $categoryedit; | |
a102baea | 58 | } |
f73cea54 SH |
59 | require_login(); |
60 | $editingon = $PAGE->user_is_editing(); | |
61 | } else { | |
62 | if ($CFG->forcelogin) { | |
ebff4779 | 63 | require_login(); |
f73cea54 SH |
64 | } |
65 | $editingon = false; | |
66 | } | |
67 | ||
68 | if (!$category->visible) { | |
69 | require_capability('moodle/category:viewhiddencategories', $context); | |
70 | } | |
71 | ||
72 | $canmanage = has_capability('moodle/category:manage', $context); | |
73 | $sesskeyprovided = !empty($sesskey) && confirm_sesskey($sesskey); | |
74 | ||
75 | // Process any category actions. | |
76 | if ($canmanage && $resort && $sesskeyprovided) { | |
77 | // Resort the category if requested | |
78 | if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) { | |
79 | $i = 1; | |
80 | foreach ($courses as $course) { | |
81 | $DB->set_field('course', 'sortorder', $category->sortorder+$i, array('id'=>$course->id)); | |
82 | $i++; | |
ebff4779 | 83 | } |
f73cea54 | 84 | fix_course_sortorder(); // should not be needed |
d2b6ba70 | 85 | } |
f73cea54 | 86 | } |
c2cb4545 | 87 | |
f73cea54 SH |
88 | // Process any course actions. |
89 | if ($editingon && $sesskeyprovided) { | |
ebff4779 | 90 | |
f73cea54 SH |
91 | // Move a specified course to a new category |
92 | if (!empty($moveto) and $data = data_submitted()) { | |
93 | // Some courses are being moved | |
94 | // user must have category update in both cats to perform this | |
95 | require_capability('moodle/category:manage', $context); | |
96 | require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto)); | |
97 | ||
98 | if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) { | |
99 | print_error('cannotfindcategory', '', '', $data->moveto); | |
52a554db | 100 | } |
49d3bab8 | 101 | |
f73cea54 SH |
102 | $courses = array(); |
103 | foreach ($data as $key => $value) { | |
104 | if (preg_match('/^c\d+$/', $key)) { | |
105 | $courseid = substr($key, 1); | |
106 | array_push($courses, $courseid); | |
f2bb0045 | 107 | |
f73cea54 SH |
108 | // check this course's category |
109 | if ($movingcourse = $DB->get_record('course', array('id'=>$courseid))) { | |
110 | if ($movingcourse->category != $id ) { | |
111 | print_error('coursedoesnotbelongtocategory'); | |
4c211e95 | 112 | } |
f73cea54 SH |
113 | } else { |
114 | print_error('cannotfindcourse'); | |
d2b6ba70 | 115 | } |
e295df44 | 116 | } |
c2cb4545 | 117 | } |
f73cea54 SH |
118 | move_courses($courses, $data->moveto); |
119 | } | |
c2cb4545 | 120 | |
f73cea54 SH |
121 | // Hide or show a course |
122 | if (!empty($hide) or !empty($show)) { | |
123 | if (!empty($hide)) { | |
124 | $course = $DB->get_record('course', array('id' => $hide)); | |
125 | $visible = 0; | |
126 | } else { | |
127 | $course = $DB->get_record('course', array('id' => $show)); | |
128 | $visible = 1; | |
129 | } | |
4c211e95 | 130 | |
f73cea54 SH |
131 | if ($course) { |
132 | $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); | |
133 | require_capability('moodle/course:visibility', $coursecontext); | |
134 | // Set the visibility of the course | |
135 | $DB->set_field('course', 'visible', $visible, array('id' => $course->id)); | |
136 | // we set the old flag when user manually changes visibility of course | |
137 | $DB->set_field('course', 'visibleold', $visible, array('id' => $course->id)); | |
d2b6ba70 | 138 | } |
f73cea54 | 139 | } |
c2cb4545 | 140 | |
c2cb4545 | 141 | |
f73cea54 SH |
142 | // Move a course up or down |
143 | if (!empty($moveup) or !empty($movedown)) { | |
144 | require_capability('moodle/category:manage', $context); | |
daa27ce4 | 145 | |
f73cea54 SH |
146 | // Ensure the course order has continuous ordering |
147 | fix_course_sortorder(); | |
148 | $swapcourse = NULL; | |
daa27ce4 | 149 | |
f73cea54 SH |
150 | if (!empty($moveup)) { |
151 | if ($movecourse = $DB->get_record('course', array('id' => $moveup))) { | |
152 | $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1)); | |
c2cb4545 | 153 | } |
f73cea54 SH |
154 | } else { |
155 | if ($movecourse = $DB->get_record('course', array('id' => $movedown))) { | |
156 | $swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1)); | |
0cbe8111 | 157 | } |
ba87a4da | 158 | } |
f73cea54 SH |
159 | if ($swapcourse and $movecourse) { |
160 | // check course's category | |
161 | if ($movecourse->category != $id) { | |
162 | print_error('coursedoesnotbelongtocategory'); | |
163 | } | |
164 | $DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id)); | |
165 | $DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id)); | |
afc45eb1 | 166 | } |
1fb3d044 | 167 | } |
168 | ||
f73cea54 SH |
169 | } // End of editing stuff |
170 | ||
171 | // Prepare the standard URL params for this page. We'll need them later. | |
172 | $urlparams = array('id' => $id); | |
173 | if ($page) { | |
174 | $urlparams['page'] = $page; | |
175 | } | |
176 | if ($perpage) { | |
177 | $urlparams['perpage'] = $perpage; | |
178 | } | |
179 | ||
180 | // Begin output | |
181 | if ($editingon && can_edit_in_category()) { | |
182 | // Integrate into the admin tree only if the user can edit categories at the top level, | |
183 | // otherwise the admin block does not appear to this user, and you get an error. | |
184 | require_once($CFG->libdir . '/adminlib.php'); | |
185 | admin_externalpage_setup('coursemgmt', '', $urlparams, $CFG->wwwroot . '/course/category.php'); | |
186 | $PAGE->set_context($context); // Ensure that we are actually showing blocks etc for the cat context | |
187 | ||
188 | $settingsnode = $PAGE->settingsnav->find_active_node(); | |
189 | if ($settingsnode) { | |
190 | $settingsnode->make_inactive(); | |
191 | $settingsnode->force_open(); | |
192 | $PAGE->navbar->add($settingsnode->text, $settingsnode->action); | |
193 | } | |
194 | echo $OUTPUT->header(); | |
195 | } else { | |
196 | $site = get_site(); | |
197 | $PAGE->set_title("$site->shortname: $category->name"); | |
198 | $PAGE->set_heading($site->fullname); | |
199 | $PAGE->set_button(print_course_search('', true, 'navbar')); | |
200 | $PAGE->set_pagelayout('coursecategory'); | |
201 | echo $OUTPUT->header(); | |
202 | } | |
203 | ||
1fb3d044 | 204 | /// Print the category selector |
f73cea54 SH |
205 | $displaylist = array(); |
206 | $notused = array(); | |
207 | make_categories_list($displaylist, $notused); | |
1fb3d044 | 208 | |
f73cea54 SH |
209 | echo '<div class="categorypicker">'; |
210 | $select = new single_select(new moodle_url('/course/category.php'), 'id', $displaylist, $category->id, null, 'switchcategory'); | |
211 | $select->set_label(get_string('categories').':'); | |
212 | echo $OUTPUT->render($select); | |
213 | echo '</div>'; | |
1fb3d044 | 214 | |
215 | /// Print current category description | |
f73cea54 SH |
216 | if (!$editingon && $category->description) { |
217 | echo $OUTPUT->box_start(); | |
218 | $options = new stdClass; | |
219 | $options->noclean = true; | |
220 | $options->para = false; | |
221 | $options->overflowdiv = true; | |
222 | if (!isset($category->descriptionformat)) { | |
223 | $category->descriptionformat = FORMAT_MOODLE; | |
1fb3d044 | 224 | } |
f73cea54 SH |
225 | $text = file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id, 'coursecat', 'description', null); |
226 | echo format_text($text, $category->descriptionformat, $options); | |
227 | echo $OUTPUT->box_end(); | |
228 | } | |
229 | ||
230 | if ($editingon && $canmanage) { | |
231 | echo $OUTPUT->container_start('buttons'); | |
232 | ||
233 | // Print button to update this category | |
234 | $url = new moodle_url('/course/editcategory.php', array('id' => $category->id)); | |
235 | echo $OUTPUT->single_button($url, get_string('editcategorythis'), 'get'); | |
236 | ||
237 | // Print button for creating new categories | |
238 | $url = new moodle_url('/course/editcategory.php', array('parent' => $category->id)); | |
239 | echo $OUTPUT->single_button($url, get_string('addsubcategory'), 'get'); | |
240 | ||
241 | echo $OUTPUT->container_end(); | |
242 | } | |
243 | ||
244 | // Print out all the sub-categories | |
245 | // In order to view hidden subcategories the user must have the viewhiddencategories | |
246 | // capability in the current category. | |
247 | if (has_capability('moodle/category:viewhiddencategories', $context)) { | |
248 | $categorywhere = ''; | |
249 | } else { | |
250 | $categorywhere = 'AND cc.visible = 1'; | |
251 | } | |
252 | // We're going to preload the context for the subcategory as we know that we | |
253 | // need it later on for formatting. | |
e141bc81 SH |
254 | |
255 | $ctxselect = context_helper::get_preload_record_columns_sql('ctx'); | |
256 | $sql = "SELECT cc.*, $ctxselect | |
f73cea54 | 257 | FROM {course_categories} cc |
e141bc81 SH |
258 | JOIN {context} ctx ON cc.id = ctx.instanceid |
259 | WHERE cc.parent = :parentid AND | |
260 | ctx.contextlevel = :contextlevel | |
f73cea54 SH |
261 | $categorywhere |
262 | ORDER BY cc.sortorder ASC"; | |
e141bc81 | 263 | $subcategories = $DB->get_recordset_sql($sql, array('parentid' => $category->id, 'contextlevel' => CONTEXT_COURSECAT)); |
f73cea54 SH |
264 | // Prepare a table to display the sub categories. |
265 | $table = new html_table; | |
266 | $table->attributes = array('border' => '0', 'cellspacing' => '2', 'cellpadding' => '4', 'class' => 'generalbox boxaligncenter category_subcategories'); | |
267 | $table->head = array(new lang_string('subcategories')); | |
268 | $table->data = array(); | |
96e78552 | 269 | $baseurl = new moodle_url('/course/category.php'); |
f73cea54 SH |
270 | foreach ($subcategories as $subcategory) { |
271 | // Preload the context we will need it to format the category name shortly. | |
e141bc81 | 272 | context_helper::preload_from_record($subcategory); |
f73cea54 SH |
273 | $context = get_context_instance(CONTEXT_COURSECAT, $subcategory->id); |
274 | // Prepare the things we need to create a link to the subcategory | |
275 | $attributes = $subcategory->visible ? array() : array('class' => 'dimmed'); | |
f73cea54 SH |
276 | $text = format_string($subcategory->name, true, array('context' => $context)); |
277 | // Add the subcategory to the table | |
7a3a0a30 SH |
278 | $baseurl->param('id', $subcategory->id); |
279 | $table->data[] = array(html_writer::link($baseurl, $text, $attributes)); | |
f73cea54 SH |
280 | } |
281 | ||
282 | $subcategorieswereshown = (count($table->data) > 0); | |
283 | if ($subcategorieswereshown) { | |
284 | echo html_writer::table($table); | |
285 | } | |
286 | ||
287 | // Print out all the courses | |
288 | $courses = get_courses_page($category->id, 'c.sortorder ASC', | |
289 | 'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible', | |
290 | $totalcount, $page*$perpage, $perpage); | |
291 | $numcourses = count($courses); | |
292 | ||
293 | if (!$courses) { | |
294 | if (empty($subcategorieswereshown)) { | |
295 | echo $OUTPUT->heading(get_string("nocoursesyet")); | |
09deab06 | 296 | } |
297 | ||
f73cea54 SH |
298 | } else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) { |
299 | echo $OUTPUT->box_start('courseboxes'); | |
300 | print_courses($category); | |
301 | echo $OUTPUT->box_end(); | |
daa27ce4 | 302 | |
f73cea54 SH |
303 | } else { |
304 | echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "/course/category.php?id=$category->id&perpage=$perpage"); | |
c2cb4545 | 305 | |
f73cea54 SH |
306 | echo '<form id="movecourses" action="category.php" method="post"><div>'; |
307 | echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; | |
308 | echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter"><tr>'; | |
309 | echo '<th class="header" scope="col">'.get_string('courses').'</th>'; | |
310 | if ($editingon) { | |
311 | echo '<th class="header" scope="col">'.get_string('edit').'</th>'; | |
312 | echo '<th class="header" scope="col">'.get_string('select').'</th>'; | |
313 | } else { | |
314 | echo '<th class="header" scope="col"> </th>'; | |
315 | } | |
316 | echo '</tr>'; | |
c2cb4545 | 317 | |
f73cea54 SH |
318 | $count = 0; |
319 | $abletomovecourses = false; // for now | |
c2cb4545 | 320 | |
f73cea54 SH |
321 | // Checking if we are at the first or at the last page, to allow courses to |
322 | // be moved up and down beyond the paging border | |
323 | if ($totalcount > $perpage) { | |
324 | $atfirstpage = ($page == 0); | |
325 | if ($perpage > 0) { | |
326 | $atlastpage = (($page + 1) == ceil($totalcount / $perpage)); | |
3d95bdb7 | 327 | } else { |
f73cea54 | 328 | $atlastpage = true; |
d2b6ba70 | 329 | } |
f73cea54 SH |
330 | } else { |
331 | $atfirstpage = true; | |
332 | $atlastpage = true; | |
333 | } | |
d2b6ba70 | 334 | |
96e78552 | 335 | $baseurl = new moodle_url('/course/category.php', $urlparams + array('sesskey' => sesskey())); |
f73cea54 SH |
336 | foreach ($courses as $acourse) { |
337 | $coursecontext = get_context_instance(CONTEXT_COURSE, $acourse->id); | |
c2cb4545 | 338 | |
f73cea54 SH |
339 | $count++; |
340 | $up = ($count > 1 || !$atfirstpage); | |
341 | $down = ($count < $numcourses || !$atlastpage); | |
c2cb4545 | 342 | |
f73cea54 SH |
343 | $linkcss = $acourse->visible ? '' : ' class="dimmed" '; |
344 | echo '<tr>'; | |
345 | $coursename = get_course_display_name_for_list($acourse); | |
346 | echo '<td><a '.$linkcss.' href="view.php?id='.$acourse->id.'">'. format_string($coursename) .'</a></td>'; | |
347 | if ($editingon) { | |
348 | echo '<td>'; | |
349 | if (has_capability('moodle/course:update', $coursecontext)) { | |
350 | $url = new moodle_url('/course/edit.php', array('id' => $acourse->id, 'category' => $id, 'returnto' => 'category')); | |
351 | echo $OUTPUT->action_icon($url, new pix_icon('t/edit', get_string('settings'))); | |
7b0d5cd5 | 352 | } |
c851eb94 | 353 | |
f73cea54 SH |
354 | // role assignment link |
355 | if (has_capability('moodle/course:enrolreview', $coursecontext)) { | |
356 | $url = new moodle_url('/enrol/users.php', array('id' => $acourse->id)); | |
357 | echo $OUTPUT->action_icon($url, new pix_icon('i/users', get_string('enrolledusers', 'enrol'))); | |
358 | } | |
e295df44 | 359 | |
f73cea54 SH |
360 | if (can_delete_course($acourse->id)) { |
361 | $url = new moodle_url('/course/delete.php', array('id' => $acourse->id)); | |
362 | echo $OUTPUT->action_icon($url, new pix_icon('t/delete', get_string('delete'))); | |
363 | } | |
e295df44 | 364 | |
f73cea54 SH |
365 | // MDL-8885, users with no capability to view hidden courses, should not be able to lock themselves out |
366 | if (has_capability('moodle/course:visibility', $coursecontext) && has_capability('moodle/course:viewhiddencourses', $coursecontext)) { | |
f73cea54 | 367 | if (!empty($acourse->visible)) { |
96e78552 | 368 | $url = new moodle_url($baseurl, array('hide' => $acourse->id)); |
f73cea54 SH |
369 | echo $OUTPUT->action_icon($url, new pix_icon('t/hide', get_string('hide'))); |
370 | } else { | |
96e78552 | 371 | $url = new moodle_url($baseurl, array('show' => $acourse->id)); |
f73cea54 | 372 | echo $OUTPUT->action_icon($url, new pix_icon('t/show', get_string('show'))); |
555b75f4 | 373 | } |
f73cea54 | 374 | } |
bbbf2d40 | 375 | |
f73cea54 SH |
376 | if (has_capability('moodle/backup:backupcourse', $coursecontext)) { |
377 | $url = new moodle_url('/backup/backup.php', array('id' => $acourse->id)); | |
378 | echo $OUTPUT->action_icon($url, new pix_icon('t/backup', get_string('backup'))); | |
379 | } | |
bbbf2d40 | 380 | |
f73cea54 SH |
381 | if (has_capability('moodle/restore:restorecourse', $coursecontext)) { |
382 | $url = new moodle_url('/backup/restorefile.php', array('contextid' => $coursecontext->id)); | |
383 | echo $OUTPUT->action_icon($url, new pix_icon('t/restore', get_string('restore'))); | |
384 | } | |
e295df44 | 385 | |
f73cea54 | 386 | if ($canmanage) { |
f73cea54 | 387 | if ($up) { |
96e78552 | 388 | $url = new moodle_url($baseurl, array('moveup' => $acourse->id)); |
f73cea54 | 389 | echo $OUTPUT->action_icon($url, new pix_icon('t/up', get_string('moveup'))); |
555b75f4 | 390 | } |
daa27ce4 | 391 | |
f73cea54 | 392 | if ($down) { |
96e78552 | 393 | $url = new moodle_url($baseurl, array('movedown' => $acourse->id)); |
f73cea54 | 394 | echo $OUTPUT->action_icon($url, new pix_icon('t/down', get_string('movedown'))); |
3d95bdb7 | 395 | } |
f73cea54 SH |
396 | $abletomovecourses = true; |
397 | } | |
e295df44 | 398 | |
f73cea54 SH |
399 | echo '</td>'; |
400 | echo '<td align="center">'; | |
401 | echo '<input type="checkbox" name="c'.$acourse->id.'" />'; | |
402 | echo '</td>'; | |
403 | } else { | |
404 | echo '<td align="right">'; | |
405 | // print enrol info | |
406 | if ($icons = enrol_get_course_info_icons($acourse)) { | |
407 | foreach ($icons as $pix_icon) { | |
408 | echo $OUTPUT->render($pix_icon); | |
3d95bdb7 | 409 | } |
c2cb4545 | 410 | } |
f73cea54 SH |
411 | if (!empty($acourse->summary)) { |
412 | $url = new moodle_url("/course/info.php?id=$acourse->id"); | |
413 | echo $OUTPUT->action_link($url, '<img alt="'.get_string('info').'" class="icon" src="'.$OUTPUT->pix_url('i/info') . '" />', | |
414 | new popup_action('click', $url, 'courseinfo'), array('title'=>get_string('summary'))); | |
415 | } | |
416 | echo "</td>"; | |
f2bb0045 | 417 | } |
f73cea54 | 418 | echo "</tr>"; |
c2cb4545 | 419 | } |
e295df44 | 420 | |
f73cea54 SH |
421 | if ($abletomovecourses) { |
422 | $movetocategories = array(); | |
423 | $notused = array(); | |
424 | make_categories_list($movetocategories, $notused, 'moodle/category:manage'); | |
425 | $movetocategories[$category->id] = get_string('moveselectedcoursesto'); | |
426 | echo '<tr><td colspan="3" align="right">'; | |
427 | echo html_writer::select($movetocategories, 'moveto', $category->id, null, array('id'=>'movetoid')); | |
428 | $PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('movecourses', 'movetoid', false)); | |
429 | echo '<input type="hidden" name="id" value="'.$category->id.'" />'; | |
430 | echo '</td></tr>'; | |
c432fd32 | 431 | } |
49d3bab8 | 432 | |
f73cea54 SH |
433 | echo '</table>'; |
434 | echo '</div></form>'; | |
435 | echo '<br />'; | |
436 | } | |
77eddcd5 | 437 | |
f73cea54 SH |
438 | echo '<div class="buttons">'; |
439 | if ($canmanage and $numcourses > 1) { | |
440 | // Print button to re-sort courses by name | |
441 | $url = new moodle_url('/course/category.php', array('id' => $category->id, 'resort' => 'name', 'sesskey' => sesskey())); | |
442 | echo $OUTPUT->single_button($url, get_string('resortcoursesbyname'), 'get'); | |
443 | } | |
444 | ||
445 | if (has_capability('moodle/course:create', $context)) { | |
446 | // Print button to create a new course | |
447 | $url = new moodle_url('/course/edit.php', array('category' => $category->id, 'returnto' => 'category')); | |
448 | echo $OUTPUT->single_button($url, get_string('addnewcourse'), 'get'); | |
449 | } | |
e295df44 | 450 | |
f73cea54 SH |
451 | if (!empty($CFG->enablecourserequests) && $category->id == $CFG->defaultrequestcategory) { |
452 | print_course_request_buttons(get_context_instance(CONTEXT_SYSTEM)); | |
453 | } | |
454 | echo '</div>'; | |
e295df44 | 455 | |
f73cea54 | 456 | print_course_search(); |
c2cb4545 | 457 | |
7a3a0a30 | 458 | echo $OUTPUT->footer(); |