2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Course and category management helper class.
20 * @package core_course
21 * @copyright 2013 Sam Hemelryk
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core_course\management
;
27 defined('MOODLE_INTERNAL') ||
die;
30 * Course and category management interface helper class.
32 * This class provides methods useful to the course and category management interfaces.
33 * Many of the methods on this class are static and serve one of two purposes.
34 * 1. encapsulate functionality in an effort to ensure minimal changes between the different
35 * methods of interaction. Specifically browser, AJAX and webservice.
36 * 2. abstract logic for acquiring actions away from output so that renderers may use them without
37 * having to include any logic or capability checks.
39 * @package core_course
40 * @copyright 2013 Sam Hemelryk
41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46 * The expanded category structure if its already being loaded from the cache.
49 protected static $expandedcategories = null;
52 * Returns course details in an array ready to be printed.
54 * @global \moodle_database $DB
55 * @param \course_in_list $course
58 public static function get_course_detail_array(\course_in_list
$course) {
61 $canaccess = $course->can_access();
63 $format = \
course_get_format($course->id
);
64 $modinfo = \
get_fast_modinfo($course->id
);
65 $modules = $modinfo->get_used_module_names();
67 if ($format->uses_sections()) {
68 foreach ($modinfo->get_section_info_all() as $section) {
69 if ($section->uservisible
) {
70 $sections[] = $format->get_section_name($section);
75 $category = \coursecat
::get($course->category
);
76 $categoryurl = new \
moodle_url('/course/management.php', array('categoryid' => $course->category
));
77 $categoryname = $category->get_formatted_name();
81 'key' => \
get_string('fullname'),
82 'value' => $course->get_formatted_fullname()
85 'key' => \
get_string('shortname'),
86 'value' => $course->get_formatted_shortname()
89 'key' => \
get_string('idnumber'),
90 'value' => s($course->idnumber
)
93 'key' => \
get_string('category'),
94 'value' => \html_writer
::link($categoryurl, $categoryname)
97 if (has_capability('moodle/site:accessallgroups', $course->get_context())) {
98 $groups = \
groups_get_course_data($course->id
);
100 'groupings' => array(
101 'key' => \
get_string('groupings', 'group'),
102 'value' => count($groups->groupings
)
105 'key' => \
get_string('groups'),
106 'value' => count($groups->groups
)
111 $names = \role_get_names
($course->get_context());
112 $sql = 'SELECT ra.roleid, COUNT(ra.id) AS rolecount
113 FROM {role_assignments} ra
114 WHERE ra.contextid = :contextid
116 $rolecounts = $DB->get_records_sql($sql, array('contextid' => $course->get_context()->id
));
117 $roledetails = array();
118 foreach ($rolecounts as $result) {
120 $a->role
= $names[$result->roleid
]->localname
;
121 $a->count
= $result->rolecount
;
122 $roledetails[] = \
get_string('assignedrolecount', 'moodle', $a);
125 $details['roleassignments'] = array(
126 'key' => \
get_string('roleassignments'),
127 'value' => join('<br />', $roledetails)
130 if ($course->can_review_enrolments()) {
131 $enrolmentlines = array();
132 $instances = \
enrol_get_instances($course->id
, true);
133 $plugins = \
enrol_get_plugins(true);
134 foreach ($instances as $instance) {
135 if (!isset($plugins[$instance->enrol
])) {
139 $plugin = $plugins[$instance->enrol
];
140 $enrolmentlines[] = $plugin->get_instance_name($instance);
142 $details['enrolmentmethods'] = array(
143 'key' => \
get_string('enrolmentmethods'),
144 'value' => join('<br />', $enrolmentlines)
148 $details['format'] = array(
149 'key' => \
get_string('format'),
150 'value' => \
course_get_format($course)->get_format_name()
152 $details['sections'] = array(
153 'key' => \
get_string('sections'),
154 'value' => join('<br />', $sections)
156 $details['modulesused'] = array(
157 'key' => \
get_string('modulesused'),
158 'value' => join('<br />', $modules)
165 * Returns an array of actions that can be performed upon a category being shown in a list.
167 * @param \coursecat $category
170 public static function get_category_listitem_actions(\coursecat
$category) {
171 $baseurl = new \
moodle_url('/course/management.php', array('categoryid' => $category->id
, 'sesskey' => \
sesskey()));
174 if ($category->can_edit()) {
175 $actions['edit'] = array(
176 'url' => new \
moodle_url('/course/editcategory.php', array('id' => $category->id
)),
177 'icon' => new \
pix_icon('t/edit', new \
lang_string('edit')),
178 'string' => new \
lang_string('edit')
183 if ($category->can_change_visibility()) {
184 // We always show both icons and then just toggle the display of the invalid option with CSS.
185 $actions['hide'] = array(
186 'url' => new \
moodle_url($baseurl, array('action' => 'hidecategory')),
187 'icon' => new \
pix_icon('t/hide', new \
lang_string('hide')),
188 'string' => new \
lang_string('hide')
190 $actions['show'] = array(
191 'url' => new \
moodle_url($baseurl, array('action' => 'showcategory')),
192 'icon' => new \
pix_icon('t/show', new \
lang_string('show')),
193 'string' => new \
lang_string('show')
198 if ($category->can_change_sortorder()) {
199 $actions['moveup'] = array(
200 'url' => new \
moodle_url($baseurl, array('action' => 'movecategoryup')),
201 'icon' => new \
pix_icon('t/up', new \
lang_string('up')),
202 'string' => new \
lang_string('up')
204 $actions['movedown'] = array(
205 'url' => new \
moodle_url($baseurl, array('action' => 'movecategorydown')),
206 'icon' => new \
pix_icon('t/down', new \
lang_string('down')),
207 'string' => new \
lang_string('down')
212 if ($category->can_resort_subcategories() && $category->has_children()) {
213 $actions['resortbyname'] = array(
214 'url' => new \
moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'name')),
215 'icon' => new \
pix_icon('t/sort', new \
lang_string('sort')),
216 'string' => new \
lang_string('resortsubcategoriesbyname', 'moodle')
218 $actions['resortbyidnumber'] = array(
219 'url' => new \
moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'idnumber')),
220 'icon' => new \
pix_icon('t/sort', new \
lang_string('sort')),
221 'string' => new \
lang_string('resortsubcategoriesbyidnumber', 'moodle')
226 if ($category->can_delete_full()) {
227 $actions['delete'] = array(
228 'url' => new \
moodle_url($baseurl, array('action' => 'deletecategory')),
229 'icon' => new \
pix_icon('t/delete', new \
lang_string('delete')),
230 'string' => new \
lang_string('delete')
235 if ($category->can_review_roles()) {
236 $actions['assignroles'] = array(
237 'url' => new \
moodle_url('/admin/roles/assign.php', array('contextid' => $category->get_context()->id
,
238 'return' => 'management')),
239 'icon' => new \
pix_icon('i/assignroles', new \
lang_string('assignroles', 'role')),
240 'string' => new \
lang_string('assignroles', 'role')
245 if ($category->can_review_permissions()) {
246 $actions['permissions'] = array(
247 'url' => new \
moodle_url('/admin/roles/permissions.php', array('contextid' => $category->get_context()->id
,
248 'return' => 'management')),
249 'icon' => new \
pix_icon('i/permissions', new \
lang_string('permissions', 'role')),
250 'string' => new \
lang_string('permissions', 'role')
255 if ($category->can_review_cohorts()) {
256 $actions['cohorts'] = array(
257 'url' => new \
moodle_url('/cohort/index.php', array('contextid' => $category->get_context()->id
)),
258 'icon' => new \
pix_icon('i/cohort', new \
lang_string('cohorts', 'cohort')),
259 'string' => new \
lang_string('cohorts', 'cohort')
264 if ($category->can_review_filters()) {
265 $actions['filters'] = array(
266 'url' => new \
moodle_url('/filter/manage.php', array('contextid' => $category->get_context()->id
,
267 'return' => 'management')),
268 'icon' => new \
pix_icon('i/filter', new \
lang_string('filters', 'admin')),
269 'string' => new \
lang_string('filters', 'admin')
277 * Returns an array of actions for a course listitem.
279 * @param \coursecat $category
280 * @param \course_in_list $course
283 public static function get_course_listitem_actions(\coursecat
$category, \course_in_list
$course) {
284 $baseurl = new \
moodle_url(
285 '/course/management.php',
286 array('courseid' => $course->id
, 'categoryid' => $course->category
, 'sesskey' => \
sesskey())
290 if ($course->can_edit()) {
292 'url' => new \
moodle_url('/course/edit.php', array('id' => $course->id
)),
293 'icon' => new \
pix_icon('t/edit', \
get_string('edit')),
294 'attributes' => array('class' => 'action-edit')
298 if ($course->can_delete()) {
300 'url' => new \
moodle_url('/course/delete.php', array('id' => $course->id
)),
301 'icon' => new \
pix_icon('t/delete', \
get_string('delete')),
302 'attributes' => array('class' => 'action-delete')
306 if ($course->can_change_visibility()) {
308 'url' => new \
moodle_url($baseurl, array('action' => 'hidecourse')),
309 'icon' => new \
pix_icon('t/hide', \
get_string('hide')),
310 'attributes' => array('data-action' => 'hide', 'class' => 'action-hide')
313 'url' => new \
moodle_url($baseurl, array('action' => 'showcourse')),
314 'icon' => new \
pix_icon('t/show', \
get_string('show')),
315 'attributes' => array('data-action' => 'show', 'class' => 'action-show')
319 if ($category->can_resort_courses()) {
321 'url' => new \
moodle_url($baseurl, array('action' => 'movecourseup')),
322 'icon' => new \
pix_icon('t/up', \
get_string('up')),
323 'attributes' => array('data-action' => 'moveup', 'class' => 'action-moveup')
326 'url' => new \
moodle_url($baseurl, array('action' => 'movecoursedown')),
327 'icon' => new \
pix_icon('t/down', \
get_string('down')),
328 'attributes' => array('data-action' => 'movedown', 'class' => 'action-movedown')
335 * Returns an array of actions that can be performed on the course being displayed.
337 * @param \course_in_list $course
340 public static function get_course_detail_actions(\course_in_list
$course) {
341 $params = array('courseid' => $course->id
, 'categoryid' => $course->category
, 'sesskey' => \
sesskey());
342 $baseurl = new \
moodle_url('/course/management.php', $params);
345 if ($course->is_uservisible()) {
346 $actions['view'] = array(
347 'url' => new \
moodle_url('/course/view.php', array('id' => $course->id
)),
348 'string' => \
get_string('view')
352 if ($course->can_edit()) {
353 $actions['edit'] = array(
354 'url' => new \
moodle_url('/course/edit.php', array('id' => $course->id
)),
355 'string' => \
get_string('edit')
359 if ($course->can_review_enrolments()) {
360 $actions['enrolledusers'] = array(
361 'url' => new \
moodle_url('/enrol/users.php', array('id' => $course->id
)),
362 'string' => \
get_string('enrolledusers', 'enrol')
366 if ($course->can_delete()) {
367 $actions['delete'] = array(
368 'url' => new \
moodle_url('/course/delete.php', array('id' => $course->id
)),
369 'string' => \
get_string('delete')
373 if ($course->can_change_visibility()) {
374 if ($course->visible
) {
375 $actions['hide'] = array(
376 'url' => new \
moodle_url($baseurl, array('action' => 'hidecourse')),
377 'string' => \
get_string('hide')
380 $actions['show'] = array(
381 'url' => new \
moodle_url($baseurl, array('action' => 'showcourse')),
382 'string' => \
get_string('show')
387 if ($course->can_backup()) {
388 $actions['backup'] = array(
389 'url' => new \
moodle_url('/backup/backup.php', array('id' => $course->id
)),
390 'string' => \
get_string('backup')
394 if ($course->can_restore()) {
395 $actions['restore'] = array(
396 'url' => new \
moodle_url('/backup/restorefile.php', array('contextid' => $course->get_context()->id
)),
397 'string' => \
get_string('restore')
404 * Resorts the courses within a category moving the given course up by one.
406 * @param \course_in_list $course
407 * @param \coursecat $category
409 * @throws \moodle_exception
411 public static function action_course_change_sortorder_up_one(\course_in_list
$course, \coursecat
$category) {
412 if (!$category->can_resort_courses()) {
413 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort');
415 return \
course_change_sortorder_by_one($course, true);
419 * Resorts the courses within a category moving the given course down by one.
421 * @param \course_in_list $course
422 * @param \coursecat $category
424 * @throws \moodle_exception
426 public static function action_course_change_sortorder_down_one(\course_in_list
$course, \coursecat
$category) {
427 if (!$category->can_resort_courses()) {
428 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort');
430 return \
course_change_sortorder_by_one($course, false);
434 * Resorts the courses within a category moving the given course up by one.
436 * @global \moodle_database $DB
437 * @param int|\stdClass $courserecordorid
440 public static function action_course_change_sortorder_up_one_by_record($courserecordorid) {
441 if (is_int($courserecordorid)) {
442 $courserecordorid = get_course($courserecordorid);
444 $course = new \
course_in_list($courserecordorid);
445 $category = \coursecat
::get($course->category
);
446 return self
::action_course_change_sortorder_up_one($course, $category);
450 * Resorts the courses within a category moving the given course down by one.
452 * @global \moodle_database $DB
453 * @param int|\stdClass $courserecordorid
456 public static function action_course_change_sortorder_down_one_by_record($courserecordorid) {
457 if (is_int($courserecordorid)) {
458 $courserecordorid = get_course($courserecordorid);
460 $course = new \
course_in_list($courserecordorid);
461 $category = \coursecat
::get($course->category
);
462 return self
::action_course_change_sortorder_down_one($course, $category);
466 * Changes the sort order so that the first course appears after the second course.
468 * @param int|\stdClass $courserecordorid
469 * @param int $moveaftercourseid
471 * @throws \moodle_exception
473 public static function action_course_change_sortorder_after_course($courserecordorid, $moveaftercourseid) {
474 $course = \
get_course($courserecordorid);
475 $category = \coursecat
::get($course->category
);
476 if (!$category->can_resort_courses()) {
477 $url = '/course/management.php?categoryid='.$course->category
;
478 throw new \
moodle_exception('nopermissions', 'error', $url, \
get_string('resortcourses', 'moodle'));
480 return \
course_change_sortorder_after_course($course, $moveaftercourseid);
484 * Makes a course visible given a \course_in_list object.
486 * @param \course_in_list $course
488 * @throws \moodle_exception
490 public static function action_course_show(\course_in_list
$course) {
491 if (!$course->can_change_visibility()) {
492 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'course_in_list::can_change_visbility');
494 return course_change_visibility($course->id
, true);
498 * Makes a course hidden given a \course_in_list object.
500 * @param \course_in_list $course
502 * @throws \moodle_exception
504 public static function action_course_hide(\course_in_list
$course) {
505 if (!$course->can_change_visibility()) {
506 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'course_in_list::can_change_visbility');
508 return course_change_visibility($course->id
, false);
512 * Makes a course visible given a course id or a database record.
514 * @global \moodle_database $DB
515 * @param int|\stdClass $courserecordorid
518 public static function action_course_show_by_record($courserecordorid) {
519 if (is_int($courserecordorid)) {
520 $courserecordorid = get_course($courserecordorid);
522 $course = new \
course_in_list($courserecordorid);
523 return self
::action_course_show($course);
527 * Makes a course hidden given a course id or a database record.
529 * @global \moodle_database $DB
530 * @param int|\stdClass $courserecordorid
533 public static function action_course_hide_by_record($courserecordorid) {
534 if (is_int($courserecordorid)) {
535 $courserecordorid = get_course($courserecordorid);
537 $course = new \
course_in_list($courserecordorid);
538 return self
::action_course_hide($course);
542 * Resort a categories subcategories shifting the given category up one.
544 * @param \coursecat $category
546 * @throws \moodle_exception
548 public static function action_category_change_sortorder_up_one(\coursecat
$category) {
549 if (!$category->can_change_sortorder()) {
550 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_sortorder');
552 return $category->change_sortorder_by_one(true);
556 * Resort a categories subcategories shifting the given category down one.
558 * @param \coursecat $category
560 * @throws \moodle_exception
562 public static function action_category_change_sortorder_down_one(\coursecat
$category) {
563 if (!$category->can_change_sortorder()) {
564 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_sortorder');
566 return $category->change_sortorder_by_one(false);
570 * Resort a categories subcategories shifting the given category up one.
572 * @param int $categoryid
575 public static function action_category_change_sortorder_up_one_by_id($categoryid) {
576 $category = \coursecat
::get($categoryid);
577 return self
::action_category_change_sortorder_up_one($category);
581 * Resort a categories subcategories shifting the given category down one.
583 * @param int $categoryid
586 public static function action_category_change_sortorder_down_one_by_id($categoryid) {
587 $category = \coursecat
::get($categoryid);
588 return self
::action_category_change_sortorder_down_one($category);
592 * Makes a category hidden given a \coursecat record.
594 * @param \coursecat $category
596 * @throws \moodle_exception
598 public static function action_category_hide(\coursecat
$category) {
599 if (!$category->can_change_visibility()) {
600 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_visbility');
607 * Makes a category visible given a \coursecat record.
609 * @param \coursecat $category
611 * @throws \moodle_exception
613 public static function action_category_show(\coursecat
$category) {
614 if (!$category->can_change_visibility()) {
615 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_change_visbility');
617 if ((int)$category->get_parent_coursecat()->visible
=== 0) {
618 // You cannot mark a category visible if its parent is hidden.
626 * Makes a category visible given a \coursecat id or database record.
628 * @param int|\stdClass $categoryid
631 public static function action_category_show_by_id($categoryid) {
632 return self
::action_category_show(\coursecat
::get($categoryid));
636 * Makes a category hidden given a \coursecat id or database record.
638 * @param int|\stdClass $categoryid
641 public static function action_category_hide_by_id($categoryid) {
642 return self
::action_category_hide(\coursecat
::get($categoryid));
646 * Resorts the sub categories of the given category.
648 * @param \coursecat $category
649 * @param string $sort One of idnumber or name.
650 * @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later.
652 * @throws \moodle_exception
654 public static function action_category_resort_subcategories(\coursecat
$category, $sort, $cleanup = true) {
655 if (!$category->can_resort_subcategories()) {
656 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort');
658 return $category->resort_subcategories($sort, $cleanup);
662 * Resorts the courses within the given category.
664 * @param \coursecat $category
665 * @param string $sort One of fullname, shortname or idnumber
667 * @throws \moodle_exception
669 public static function action_category_resort_courses(\coursecat
$category, $sort) {
670 if (!$category->can_resort_courses()) {
671 throw new \
moodle_exception('permissiondenied', 'error', '', null, 'coursecat::can_resort');
673 return $category->resort_courses($sort);
677 * Moves courses out of one category and into a new category.
679 * @param \coursecat $oldcategory The category we are moving courses out of.
680 * @param \coursecat $newcategory The category we are moving courses into.
681 * @param array $courseids The ID's of the courses we want to move.
682 * @return bool True on success.
683 * @throws \moodle_exception
685 public static function action_category_move_courses_into(\coursecat
$oldcategory, \coursecat
$newcategory, array $courseids) {
688 list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED
);
689 $params['categoryid'] = $oldcategory->id
;
690 $sql = "SELECT c.id FROM {course} c WHERE c.id {$where} AND c.category <> :categoryid";
691 if ($DB->record_exists_sql($sql, $params)) {
692 // Likely being tinkered with.
693 throw new \
moodle_exception('coursedoesnotbelongtocategory');
696 // All courses are currently within the old category.
697 return self
::move_courses_into_category($newcategory, $courseids);
701 * Returns the view modes for the management interface.
704 public static function get_management_viewmodes() {
706 'combined' => new \
lang_string('categoriesandcoures'),
707 'categories' => new \
lang_string('categories'),
708 'courses' => new \
lang_string('courses')
713 * Search for courses with matching params.
715 * Please note that only one of search, blocklist, or modulelist can be specified at a time.
716 * Specifying more than one will result in only the first being used.
718 * @param string $search Words to search for. We search fullname, shortname, idnumber and summary.
719 * @param int $blocklist The ID of a block, courses will only be returned if they use this block.
720 * @param string $modulelist The name of a module (relates to database table name). Only courses containing this module
722 * @param int $page The page number to display, starting at 0.
723 * @param int $perpage The number of courses to display per page.
726 public static function search_courses($search, $blocklist, $modulelist, $page = 0, $perpage = null) {
729 if ($perpage === null) {
730 $perpage = $CFG->coursesperpage
;
733 $searchcriteria = array();
734 if (!empty($search)) {
735 $searchcriteria = array('search' => $search);
736 } else if (!empty($blocklist)) {
737 $searchcriteria = array('blocklist' => $blocklist);
738 } else if (!empty($modulelist)) {
739 $searchcriteria = array('modulelist' => $modulelist);
742 $courses = \coursecat
::get(0)->search_courses($searchcriteria, array(
744 'offset' => $page * $perpage,
746 'sort' => array('fullname' => 1)
748 $totalcount = \coursecat
::get(0)->search_courses_count($searchcriteria, array('recursive' => true));
750 return array($courses, \
count($courses), $totalcount);
754 * Moves one or more courses out of the category they are currently in and into a new category.
756 * This function works much the same way as action_category_move_courses_into however it allows courses from multiple
757 * categories to be moved into a single category.
759 * @param int|\coursecat $categoryorid The category to move them into.
760 * @param array|int $courseids An array of course id's or optionally just a single course id.
761 * @return bool True on success or false on failure.
762 * @throws \moodle_exception
764 public static function move_courses_into_category($categoryorid, $courseids = array()) {
766 if (!is_array($courseids)) {
767 // Just a single course ID.
768 $courseids = array($courseids);
770 // Bulk move courses from one category to another.
771 if (count($courseids) === 0) {
774 if ($categoryorid instanceof \coursecat
) {
775 $moveto = $categoryorid;
777 $moveto = \coursecat
::get($categoryorid);
779 if (!$moveto->can_move_courses_out_of() ||
!$moveto->can_move_courses_into()) {
780 throw new \
moodle_exception('cannotmovecourses');
783 list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED
);
784 $params['categoryid'] = $moveto->id
;
785 $sql = "SELECT c.id, c.category FROM {course} c WHERE c.id {$where} AND c.category <> :categoryid";
786 $courses = $DB->get_records_sql($sql, $params);
788 foreach ($courseids as $id) {
789 if (!isset($courses[$id])) {
790 throw new \
moodle_exception('invalidcourseid');
792 $catid = $courses[$id]->category
;
793 if (!isset($checks[$catid])) {
794 $coursecat = \coursecat
::get($catid);
795 $checks[$catid] = $coursecat->can_move_courses_out_of() && $coursecat->can_move_courses_into();
797 if (!$checks[$catid]) {
798 throw new \
moodle_exception('cannotmovecourses');
801 return \
move_courses($courseids, $moveto->id
);
805 * Returns an array of courseids and visiblity for all courses within the given category.
806 * @param int $categoryid
809 public static function get_category_courses_visibility($categoryid) {
811 $sql = "SELECT c.id, c.visible
813 WHERE c.category = :category";
814 $params = array('category' => (int)$categoryid);
815 return $DB->get_records_sql($sql, $params);
819 * Returns an array of all categoryids that have the given category as a parent and their visible value.
820 * @param int $categoryid
823 public static function get_category_children_visibility($categoryid) {
825 $category = \coursecat
::get($categoryid);
826 $select = $DB->sql_like('path', ':path');
827 $path = $category->path
. '/%';
829 $sql = "SELECT c.id, c.visible
830 FROM {course_categories} c
832 $params = array('path' => $path);
833 return $DB->get_records_sql($sql, $params);
837 * Records when a category is expanded or collapsed so that when the user
839 * @param \coursecat $coursecat The category we're working with.
840 * @param bool $expanded True if the category is expanded now.
842 public static function record_expanded_category(\coursecat
$coursecat, $expanded = true) {
843 // If this ever changes we are going to reset it and reload the categories as required.
844 self
::$expandedcategories = null;
845 $categoryid = $coursecat->id
;
846 $path = $coursecat->get_parents();
847 /* @var \cache_session $cache */
848 $cache = \cache
::make('core', 'userselections');
849 $categories = $cache->get('categorymanagementexpanded');
850 if (!is_array($categories)) {
852 // No categories recorded, nothing to remove.
855 $categories = array();
859 foreach ($coursecat->get_parents() as $path) {
860 if (!isset($ref[$path]) ||
!is_array($ref[$path])) {
861 $ref[$path] = array();
865 if (!isset($ref[$categoryid])) {
866 $ref[$categoryid] = true;
871 foreach ($coursecat->get_parents() as $path) {
872 if (!isset($ref[$path])) {
879 $ref[$categoryid] = null;
880 unset($ref[$categoryid]);
883 $cache->set('categorymanagementexpanded', $categories);
887 * Returns the categories that should be expanded when displaying the interface.
889 * @param int|null $withpath If specified a path to require as the parent.
890 * @return \coursecat[] An array of Category ID's to expand.
892 public static function get_expanded_categories($withpath = null) {
893 if (self
::$expandedcategories === null) {
894 /* @var \cache_session $cache */
895 $cache = \cache
::make('core', 'userselections');
896 self
::$expandedcategories = $cache->get('categorymanagementexpanded');
897 if (self
::$expandedcategories === false) {
898 self
::$expandedcategories = array();
901 if (empty($withpath)) {
902 return array_keys(self
::$expandedcategories);
904 $parents = explode('/', trim($withpath, '/'));
905 $ref =& self
::$expandedcategories;
906 foreach ($parents as $parent) {
907 if (!isset($ref[$parent])) {
910 $ref =& $ref[$parent];
912 if (is_array($ref)) {
913 return array_keys($ref);
915 return array($parent);