/** * Get the list of categories leading to this course. * * This function is used by {@link navbar::get_items()} to add back the "courses" * node and category chain leading to the current course. Note that this is only ever * called for the current course, so we don't need to bother taking in any parameters. * * @return array */ private function get_course_categories() { global $CFG; require_once $CFG->dirroot . '/course/lib.php'; require_once $CFG->libdir . '/coursecatlib.php'; $categories = array(); $cap = 'moodle/category:viewhiddencategories'; $showcategories = coursecat::count_all() > 1; if ($showcategories) { foreach ($this->page->categories as $category) { if (!$category->visible && !has_capability($cap, get_category_or_system_context($category->parent))) { continue; } $url = new moodle_url('/course/index.php', array('categoryid' => $category->id)); $name = format_string($category->name, true, array('context' => context_coursecat::instance($category->id))); $categorynode = breadcrumb_navigation_node::create($name, $url, self::TYPE_CATEGORY, null, $category->id); if (!$category->visible) { $categorynode->hidden = true; } $categories[] = $categorynode; } } // Don't show the 'course' node if enrolled in this course. if (!is_enrolled(context_course::instance($this->page->course->id, null, '', true))) { $courses = $this->page->navigation->get('courses'); if (!$courses) { // Courses node may not be present. $courses = breadcrumb_navigation_node::create(get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_CONTAINER); } $categories[] = $courses; } return $categories; }
move_category($cattomove, $newparent); } } } /// Hide or show a category if ($hide and confirm_sesskey()) { if ($tempcat = $DB->get_record('course_categories', array('id' => $hide))) { require_capability('moodle/category:manage', get_category_or_system_context($tempcat->parent)); if ($tempcat->visible == 1) { course_category_hide($tempcat); } } } else { if ($show and confirm_sesskey()) { if ($tempcat = $DB->get_record('course_categories', array('id' => $show))) { require_capability('moodle/category:manage', get_category_or_system_context($tempcat->parent)); if ($tempcat->visible == 0) { course_category_show($tempcat); } } } } /// Move a category up or down if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) { fix_course_sortorder(); $swapcategory = NULL; if (!empty($moveup)) { require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveup)); if ($movecategory = $DB->get_record('course_categories', array('id' => $moveup))) { if ($swapcategory = $DB->get_records_select('course_categories', "sortorder<? AND parent=?", array($movecategory->sortorder, $movecategory->parent), 'sortorder DESC', '*', 0, 1)) { $swapcategory = reset($swapcategory);
/** * Delete categories * * @param array $categories A list of category ids * @return array * @since Moodle 2.3 */ public static function delete_categories($categories) { global $CFG, $DB; require_once $CFG->dirroot . "/course/lib.php"; // Validate parameters. $params = self::validate_parameters(self::delete_categories_parameters(), array('categories' => $categories)); $transaction = $DB->start_delegated_transaction(); foreach ($params['categories'] as $category) { if (!($deletecat = $DB->get_record('course_categories', array('id' => $category['id'])))) { throw new moodle_exception('unknowcategory'); } $context = context_coursecat::instance($deletecat->id); require_capability('moodle/category:manage', $context); self::validate_context($context); self::validate_context(get_category_or_system_context($deletecat->parent)); if ($category['recursive']) { // If recursive was specified, then we recursively delete the category's contents. category_delete_full($deletecat, false); } else { // In this situation, we don't delete the category's contents, we either move it to newparent or parent. // If the parent is the root, moving is not supported (because a course must always be inside a category). // We must move to an existing category. if (!empty($category['newparent'])) { if (!$DB->record_exists('course_categories', array('id' => $category['newparent']))) { throw new moodle_exception('unknowcategory'); } $newparent = $category['newparent']; } else { $newparent = $deletecat->parent; } // This operation is not allowed. We must move contents to an existing category. if ($newparent == 0) { throw new moodle_exception('movecatcontentstoroot'); } $parentcontext = get_category_or_system_context($newparent); require_capability('moodle/category:manage', $parentcontext); self::validate_context($parentcontext); category_delete_move($deletecat, $newparent, false); } } $transaction->allow_commit(); }
/** * Delete categories * * @param array $categories A list of category ids * @return array * @since Moodle 2.3 */ public static function delete_categories($categories) { global $CFG, $DB; require_once($CFG->dirroot . "/course/lib.php"); require_once($CFG->libdir . "/coursecatlib.php"); // Validate parameters. $params = self::validate_parameters(self::delete_categories_parameters(), array('categories' => $categories)); $transaction = $DB->start_delegated_transaction(); foreach ($params['categories'] as $category) { $deletecat = coursecat::get($category['id'], MUST_EXIST); $context = context_coursecat::instance($deletecat->id); require_capability('moodle/category:manage', $context); self::validate_context($context); self::validate_context(get_category_or_system_context($deletecat->parent)); if ($category['recursive']) { // If recursive was specified, then we recursively delete the category's contents. if ($deletecat->can_delete_full()) { $deletecat->delete_full(false); } else { throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name()); } } else { // In this situation, we don't delete the category's contents, we either move it to newparent or parent. // If the parent is the root, moving is not supported (because a course must always be inside a category). // We must move to an existing category. if (!empty($category['newparent'])) { $newparentcat = coursecat::get($category['newparent']); } else { $newparentcat = coursecat::get($deletecat->parent); } // This operation is not allowed. We must move contents to an existing category. if (!$newparentcat->id) { throw new moodle_exception('movecatcontentstoroot'); } self::validate_context(context_coursecat::instance($newparentcat->id)); if ($deletecat->can_move_content_to($newparentcat->id)) { $deletecat->delete_move($newparentcat->id, false); } else { throw new moodle_exception('youcannotdeletecategory', '', '', $deletecat->get_formatted_name()); } } } $transaction->allow_commit(); }
/** * Returns true if the user has the manage capability on the parent category. * @return bool */ public function parent_has_manage_capability() { return has_capability('moodle/category:manage', get_category_or_system_context($this->parent)); }
/** * Does the user have permission to edit things in this category? * * @param integer $categoryid The id of the category we are showing, or 0 for system context. * @return boolean has_any_capability(array(...), ...); in the appropriate context. */ function can_edit_in_category($categoryid = 0) { $context = get_category_or_system_context($categoryid); return has_any_capability(array('moodle/category:manage', 'moodle/course:create'), $context); }
/** * Renders HTML to display particular course category - list of it's subcategories and courses * * Invoked from /course/index.php * * @param int|stdClass|coursecat $category */ public function course_category($category) { global $CFG; require_once $CFG->libdir . '/coursecatlib.php'; $coursecat = coursecat::get(is_object($category) ? $category->id : $category); $site = get_site(); $output = ''; if (can_edit_in_category($coursecat->id)) { // Add 'Manage' button if user has permissions to edit this category. $managebutton = $this->single_button(new moodle_url('/course/management.php', array('categoryid' => $coursecat->id)), get_string('managecourses'), 'get'); $this->page->set_button($managebutton); } if (!$coursecat->id) { if (coursecat::count_all() == 1) { // There exists only one category in the system, do not display link to it $coursecat = coursecat::get_default(); $strfulllistofcourses = get_string('fulllistofcourses'); $this->page->set_title("{$site->shortname}: {$strfulllistofcourses}"); } else { $strcategories = get_string('categories'); $this->page->set_title("{$site->shortname}: {$strcategories}"); } } else { $this->page->set_title("{$site->shortname}: " . $coursecat->get_formatted_name()); // Print the category selector $output .= html_writer::start_tag('div', array('class' => 'categorypicker')); $select = new single_select(new moodle_url('/course/index.php'), 'categoryid', coursecat::make_categories_list(), $coursecat->id, null, 'switchcategory'); $select->set_label(get_string('categories') . ':'); $output .= $this->render($select); $output .= html_writer::end_tag('div'); // .categorypicker } // Print current category description $chelper = new coursecat_helper(); if ($description = $chelper->get_category_formatted_description($coursecat)) { $output .= $this->box($description, array('class' => 'generalbox info')); } // Prepare parameters for courses and categories lists in the tree $chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_AUTO)->set_attributes(array('class' => 'category-browse category-browse-' . $coursecat->id)); $coursedisplayoptions = array(); $catdisplayoptions = array(); $browse = optional_param('browse', null, PARAM_ALPHA); $perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); $baseurl = new moodle_url('/course/index.php'); if ($coursecat->id) { $baseurl->param('categoryid', $coursecat->id); } if ($perpage != $CFG->coursesperpage) { $baseurl->param('perpage', $perpage); } $coursedisplayoptions['limit'] = $perpage; $catdisplayoptions['limit'] = $perpage; if ($browse === 'courses' || !$coursecat->has_children()) { $coursedisplayoptions['offset'] = $page * $perpage; $coursedisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'courses')); $catdisplayoptions['nodisplay'] = true; $catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories')); $catdisplayoptions['viewmoretext'] = new lang_string('viewallsubcategories'); } else { if ($browse === 'categories' || !$coursecat->has_courses()) { $coursedisplayoptions['nodisplay'] = true; $catdisplayoptions['offset'] = $page * $perpage; $catdisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'categories')); $coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses')); $coursedisplayoptions['viewmoretext'] = new lang_string('viewallcourses'); } else { // we have a category that has both subcategories and courses, display pagination separately $coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses', 'page' => 1)); $catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories', 'page' => 1)); } } $chelper->set_courses_display_options($coursedisplayoptions)->set_categories_display_options($catdisplayoptions); // Add course search form. $output .= $this->course_search_form(); // Display course category tree. $output .= $this->coursecat_tree($chelper, $coursecat); // Add action buttons $output .= $this->container_start('buttons'); $context = get_category_or_system_context($coursecat->id); if (has_capability('moodle/course:create', $context)) { // Print link to create a new course, for the 1st available category. if ($coursecat->id) { $url = new moodle_url('/course/edit.php', array('category' => $coursecat->id, 'returnto' => 'category')); } else { $url = new moodle_url('/course/edit.php', array('category' => $CFG->defaultrequestcategory, 'returnto' => 'topcat')); } $output .= $this->single_button($url, get_string('addnewcourse'), 'get'); } ob_start(); if (coursecat::count_all() == 1) { print_course_request_buttons(context_system::instance()); } else { print_course_request_buttons($context); } $output .= ob_get_contents(); ob_end_clean(); $output .= $this->container_end(); return $output; }
} else { if ($data = $mform->get_data()) { $newcategory = new stdClass(); $newcategory->name = $data->name; $newcategory->description = $data->description; $newcategory->parent = $data->parent; // if $data->parent = 0, the new category will be a top-level category if (isset($data->theme) && !empty($CFG->allowcategorythemes)) { $newcategory->theme = $data->theme; } if ($id) { // Update an existing category. $newcategory->id = $category->id; if ($newcategory->parent != $category->parent) { // check category manage capability if parent changed require_capability('moodle/category:manage', get_category_or_system_context((int) $newcategory->parent)); $parent_cat = get_record('course_categories', 'id', $newcategory->parent); move_category($newcategory, $parent_cat); } if (!update_record('course_categories', $newcategory)) { error("Could not update the category '{$newcategory->name}' "); } fix_course_sortorder(); } else { // Create a new category. $newcategory->sortorder = 999; if (!($newcategory->id = insert_record('course_categories', $newcategory))) { error("Could not insert the new category '{$newcategory->name}' "); } $newcategory->context = get_context_instance(CONTEXT_COURSECAT, $newcategory->id); mark_context_dirty($newcategory->context->path);
/** * Prints the turn editing on/off button on course/index.php or course/category.php. * * @param integer $categoryid The id of the category we are showing, or 0 for system context. * @return string HTML of the editing button, or empty string, if this user is not allowed * to see it. */ function update_category_button($categoryid = 0) { global $CFG, $USER; // Check permissions. $context = get_category_or_system_context($categoryid); if (!has_any_capability(array('moodle/category:manage', 'moodle/course:create'), $context)) { return ''; } // Work out the appropriate action. if (!empty($USER->categoryediting)) { $label = get_string('turneditingoff'); $edit = 'off'; } else { $label = get_string('turneditingon'); $edit = 'on'; } // Generate the button HTML. $options = array('categoryedit' => $edit, 'sesskey' => sesskey()); if ($categoryid) { $options['id'] = $categoryid; $page = 'category.php'; } else { $page = 'index.php'; } return print_single_button($CFG->wwwroot . '/course/' . $page, $options, $label, 'get', '', true); }
/** * Get the list of categories leading to this course. * * This function is used by {@link navbar::get_items()} to add back the "courses" * node and category chain leading to the current course. Note that this is only ever * called for the current course, so we don't need to bother taking in any parameters. * * @return array */ private function get_course_categories() { global $CFG; require_once($CFG->dirroot.'/course/lib.php'); $categories = array(); $cap = 'moodle/category:viewhiddencategories'; foreach ($this->page->categories as $category) { if (!$category->visible && !has_capability($cap, get_category_or_system_context($category->parent))) { continue; } $url = new moodle_url('/course/index.php', array('categoryid' => $category->id)); $name = format_string($category->name, true, array('context' => context_coursecat::instance($category->id))); $categorynode = navigation_node::create($name, $url, self::TYPE_CATEGORY, null, $category->id); if (!$category->visible) { $categorynode->hidden = true; } $categories[] = $categorynode; } if (is_enrolled(context_course::instance($this->page->course->id))) { $courses = $this->page->navigation->get('mycourses'); } else { $courses = $this->page->navigation->get('courses'); } if (!$courses) { // Courses node may not be present. $courses = navigation_node::create( get_string('courses'), new moodle_url('/course/index.php'), self::TYPE_CONTAINER ); } $categories[] = $courses; return $categories; }
/** * Renders HTML to display particular course category - list of it's subcategories and courses * * Invoked from /course/index.php * * @param int|stdClass|coursecat $category */ public function course_category($category) { global $CFG, $USER; require_once $CFG->dirroot . '/lib/pagelib.php'; require_once $CFG->libdir . '/coursecatlib.php'; $coursecat = coursecat::get(is_object($category) ? $category->id : $category); $site = get_site(); $output = '<h2>Matières</h2>'; // Print current category description $chelper = new coursecat_helper(); if ($description = $chelper->get_category_formatted_description($coursecat)) { $output .= $this->box($description, array('class' => 'generalbox info')); } // Prepare parameters for courses and categories lists in the tree $chelper->set_show_courses(10)->set_attributes(array('class' => 'category-browse category-browse-' . $coursecat->id)); $coursedisplayoptions = array(); $catdisplayoptions = array(); $browse = optional_param('browse', null, PARAM_ALPHA); $perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); $page = optional_param('page', 0, PARAM_INT); $baseurl = new moodle_url('/local/template_course/index.php'); if ($coursecat->id) { //$baseurl->param('categoryid', $coursecat->id); } if ($perpage != $CFG->coursesperpage) { $baseurl->param('perpage', $perpage); } //PAGINACIO $coursedisplayoptions['limit'] = $perpage; $catdisplayoptions['limit'] = $perpage; if ($browse === 'courses' || !$coursecat->has_children()) { $coursedisplayoptions['offset'] = $page * $perpage; $coursedisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'courses')); $catdisplayoptions['nodisplay'] = true; $catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories')); $catdisplayoptions['viewmoretext'] = new lang_string('viewallsubcategories'); } else { if ($browse === 'categories' || !$coursecat->has_courses()) { $coursedisplayoptions['nodisplay'] = true; $catdisplayoptions['offset'] = $page * $perpage; $catdisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'categories')); $coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses')); $coursedisplayoptions['viewmoretext'] = new lang_string('viewallcourses'); } else { // we have a category that has both subcategories and courses, display pagination separately $coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses', 'page' => 1)); $catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories', 'page' => 1)); } } $chelper->set_courses_display_options($coursedisplayoptions)->set_categories_display_options($catdisplayoptions); // Display course category tree $output .= $this->coursecat_tree($chelper, $coursecat); // Add course search form (if we are inside category it was already added to the navbar) if (!$coursecat->id) { $output .= $this->course_search_form(); } // Add action buttons $output .= $this->container_start('buttons'); $context = get_category_or_system_context($coursecat->id); if (has_capability('moodle/course:create', $context)) { $url = new moodle_url('/local/template_course/edit.php', array('returnto' => 'category', 'edit' => 'on')); $output .= $this->single_button($url, 'Ajouter une nouvelle matière', 'get'); } ob_start(); if (coursecat::count_all() == 1) { print_course_request_buttons(context_system::instance()); } else { print_course_request_buttons($context); } $output .= ob_get_contents(); ob_end_clean(); $output .= $this->container_end(); return $output; }