course categories: Fix many bugs with category editing and permissions. Clean up code.

Bugs: MDL-17479, MDL-16426, MDL-16063, MDL-16013, MDL-15658, MDL-15556, MDL-15161, MDL-14925, MDL-13742, MDL-11557.

* Simplify category editing permissions to just moodle/category:manage and moodle/category:seehiddencategories.
* Enforce those correctly. (Note MDL 17502 is still outstanding.)
* Don't screw up category sort order when you just edit name or description.
* Niceties like where redirects go when you cancel or submit forms.
* Make sure a global course creator can see the site admin block.
* Don't allow a category to be made the child of one of its children!
* General code cleanup to bring key files more in line with best pracitice.

Apologies for the fact it is one big patch, rather than a series of smaller patches. However, categoryedit.php, category.php and index.php where in pretty bad shape and needed significant cleaning up. categoryedit.php, in particular, was almost completely rewritten.

Merged from MOODLE_19_STABLE.
This commit is contained in:
tjhunt 2008-12-04 08:53:10 +00:00
parent 4faace3781
commit 8ed5dd63ee
18 changed files with 501 additions and 721 deletions

View File

@ -4,10 +4,11 @@
if ($hassiteconfig
or has_capability('moodle/site:backup', $systemcontext)
or has_capability('moodle/category:update', $systemcontext)) { // speedup for non-admins, add all caps used on this page
or has_capability('moodle/category:manage', $systemcontext)
or has_capability('moodle/course:create', $systemcontext)) { // speedup for non-admins, add all caps used on this page
$ADMIN->add('courses', new admin_externalpage('coursemgmt', get_string('coursemgmt', 'admin'), $CFG->wwwroot . '/course/index.php?categoryedit=on','moodle/category:update'));
$ADMIN->add('courses', new admin_externalpage('coursemgmt', get_string('coursemgmt', 'admin'), $CFG->wwwroot . '/course/index.php?categoryedit=on',
array('moodle/category:manage', 'moodle/course:create')));
$ADMIN->add('courses', new admin_enrolment_page());

View File

@ -6,25 +6,23 @@
require_once("../config.php");
require_once("lib.php");
$id = required_param('id', PARAM_INT); // Category id
$page = optional_param('page', 0, PARAM_INT); // which page to show
$perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page
$id = required_param('id', PARAM_INT); // Category id
$page = optional_param('page', 0, PARAM_INT); // which page to show
$perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page
$categoryedit = optional_param('categoryedit', -1, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$moveup = optional_param('moveup', 0, PARAM_INT);
$movedown = optional_param('movedown', 0, PARAM_INT);
$moveto = optional_param('moveto', 0, PARAM_INT);
$rename = optional_param('rename', '', PARAM_TEXT);
$resort = optional_param('resort', 0, PARAM_BOOL);
$categorytheme= optional_param('categorytheme', false, PARAM_SAFEDIR);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$moveup = optional_param('moveup', 0, PARAM_INT);
$movedown = optional_param('movedown', 0, PARAM_INT);
$moveto = optional_param('moveto', 0, PARAM_INT);
$resort = optional_param('resort', 0, PARAM_BOOL);
if ($CFG->forcelogin) {
require_login();
}
if (!$site = get_site()) {
print_error("siteisnotdefined", 'debug');
print_error('siteisnotdefined', 'debug');
}
if (empty($id)) {
@ -38,45 +36,24 @@
if (!$category = $DB->get_record("course_categories", array("id"=>$id))) {
print_error("unknowcategory");
}
if (!$category->visible) {
require_capability('moodle/category:viewhiddencategories', $context);
}
if (has_capability('moodle/course:create', $context)) {
if (update_category_button($category->id)) {
if ($categoryedit !== -1) {
$USER->categoryediting = $categoryedit;
}
$navbaritem = update_category_button($category->id);
$creatorediting = !empty($USER->categoryediting);
$adminediting = (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and $creatorediting);
$editingon = !empty($USER->categoryediting);
$navbaritem = update_category_button($category->id); // Must call this again after updating the state.
} else {
if (!$category->visible) {
print_error('notavailable', 'error');
}
$navbaritem = print_course_search("", true, "navbar");
$adminediting = false;
$creatorediting = false;
$navbaritem = print_course_search('', true, 'navbar');
$editingon = false;
}
if (has_capability('moodle/category:update', $context)) {
/// Rename the category if requested
if (!empty($rename) and confirm_sesskey()) {
if (!$DB->set_field("course_categories", "name", $rename, array("id"=>$category->id))) {
notify("An error occurred while renaming the category");
}
$category->name = $rename;
//trigger events
events_trigger('course_category_updated', $category);
}
/// Set the category theme if requested
if (($categorytheme !== false) and confirm_sesskey()) {
$category->theme = $categorytheme;
if (!$DB->set_field('course_categories', 'theme', $category->theme, array('id'=>$category->id))) {
notify('An error occurred while setting the theme');
}
}
// Process any category actions.
if (has_capability('moodle/category:manage', $context)) {
/// Resort the category if requested
if ($resort and confirm_sesskey()) {
if ($courses = get_courses($category->id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
$i = 1;
@ -89,88 +66,75 @@
}
}
if(! empty($CFG->allowcategorythemes) ){
if(isset($category->theme)){
// specifying theme here saves us some dbqs
theme_setup($category->theme);
}
if(!empty($CFG->allowcategorythemes) && isset($category->theme)) {
// specifying theme here saves us some dbqs
theme_setup($category->theme);
}
/// Print headings
$numcategories = $DB->count_records('course_categories');
$numcategories = $DB->count_records("course_categories");
$stradministration = get_string("administration");
$strcategories = get_string("categories");
$strcategory = get_string("category");
$strcourses = get_string("courses");
$stradministration = get_string('administration');
$strcategories = get_string('categories');
$strcategory = get_string('category');
$strcourses = get_string('courses');
$navlinks = array();
$navlinks[] = array('name' => $strcategories, 'link' => 'index.php', 'type' => 'misc');
$navlinks[] = array('name' => format_string($category->name), 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
if ($creatorediting) {
if ($adminediting) {
// modify this to treat this as an admin page
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('coursemgmt');
admin_externalpage_print_header();
} else {
print_header("$site->shortname: $category->name", "$site->fullname: $strcourses", $navigation, "", "", true, $navbaritem);
}
if ($editingon && update_category_button()) {
// Integrate into the admin tree only if the user can edit categories at the top level,
// otherwise the admin block does not appear to this user, and you get an error.
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('coursemgmt');
admin_externalpage_print_header();
} else {
print_header("$site->shortname: $category->name", "$site->fullname: $strcourses", $navigation, "", "", true, $navbaritem);
print_header("$site->shortname: $category->name", "$site->fullname: $strcourses", $navigation, '', '', true, $navbaritem);
}
/// Print button to turn editing off
if ($adminediting) {
if ($editingon) {
echo '<div class="categoryediting button">'.update_category_button($category->id).'</div>';
}
/// Print link to roles
if (has_capability('moodle/role:assign', $context)) {
echo '<div class="rolelink"><a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
$context->id.'">'.get_string('assignroles','role').'</a></div>';
}
/// Print the category selector
$displaylist = array();
$parentlist = array();
make_categories_list($displaylist, $parentlist, "");
$notused = array();
make_categories_list($displaylist, $notused);
echo '<div class="categorypicker">';
popup_form('category.php?id=', $displaylist, 'switchcategory', $category->id, '', '', '', false, 'self', $strcategories.':');
echo '</div>';
/// Print current category description
if (!$creatorediting && $category->description) {
if (!$editingon && $category->description) {
print_box_start();
echo format_text($category->description); // for multilang filter
print_box_end();
}
/// Editing functions
if ($creatorediting) {
/// Process any course actions.
if ($editingon) {
/// Move a specified course to a new category
if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) { // Some courses are being moved
// user must have category update in both cats to perform this
require_capability('moodle/category:update', $context);
require_capability('moodle/category:update', get_context_instance(CONTEXT_COURSECAT, $moveto));
require_capability('moodle/category:manage', $context);
require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $moveto));
if (! $destcategory = $DB->get_record("course_categories", array("id"=>$data->moveto))) {
print_error("cannotfindcategory", '', '', $data->moveto);
if (!$destcategory = $DB->get_record('course_categories', array('id' => $data->moveto))) {
print_error('cannotfindcategory', '', '', $data->moveto);
}
$courses = array();
foreach ( $data as $key => $value ) {
foreach ($data as $key => $value) {
if (preg_match('/^c\d+$/', $key)) {
array_push($courses, substr($key, 1));
}
@ -179,73 +143,67 @@
}
/// Hide or show a course
if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
require_capability('moodle/course:visibility', $context);
if (!empty($hide)) {
$course = $DB->get_record("course", array("id"=>$hide));
$course = $DB->get_record('course', array('id' => $hide));
$visible = 0;
} else {
$course = $DB->get_record("course", array("id"=>$show));
$course = $DB->get_record('course', array('id' => $show));
$visible = 1;
}
if ($course) {
if (!$DB->set_field("course", "visible", $visible, array("id"=>$course->id))) {
notify("Could not update that course!");
if (!$DB->set_field('course', 'visible', $visible, array('id' => $course->id))) {
print_error('errorupdatingcoursevisibility');
}
}
}
/// Move a course up or down
if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
require_capability('moodle/category:update', $context);
require_capability('moodle/category:manage', $context);
// ensure the course order has continuous ordering
// Ensure the course order has continuous ordering
fix_course_sortorder();
$swapcourse = NULL;
if (!empty($moveup)) {
if ($movecourse = $DB->get_record('course', array('id'=>$moveup))) {
$swapcourse = $DB->get_record('course', array('sortorder'=>$movecourse->sortorder-1));
if ($movecourse = $DB->get_record('course', array('id' => $moveup))) {
$swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder - 1));
}
} else {
if ($movecourse = $DB->get_record('course', array('id'=>$movedown))) {
$swapcourse = $DB->get_record('course', array('sortorder'=>$movecourse->sortorder+1));
if ($movecourse = $DB->get_record('course', array('id' => $movedown))) {
$swapcourse = $DB->get_record('course', array('sortorder' => $movecourse->sortorder + 1));
}
}
if ($swapcourse and $movecourse) {
$DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id'=>$movecourse->id));
$DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id'=>$swapcourse->id));
$DB->set_field('course', 'sortorder', $swapcourse->sortorder, array('id' => $movecourse->id));
$DB->set_field('course', 'sortorder', $movecourse->sortorder, array('id' => $swapcourse->id));
}
}
} // End of editing stuff
if ($editingon && has_capability('moodle/category:manage', $context)) {
echo '<div class="buttons">';
if ($creatorediting) {
echo '<div class="buttons">';
if (has_capability('moodle/category:update', $context)) { // Print button to update this category
unset($options);
$options['id'] = $category->id;
print_single_button('editcategory.php', $options, get_string('editcategorythis'), 'get');
}
// Print button to update this category
$options = array('id' => $category->id);
print_single_button($CFG->wwwroot.'/course/editcategory.php', $options, get_string('editcategorythis'), 'get');
// Print button for creating new categories
$options = array('parent' => $category->id);
print_single_button($CFG->wwwroot.'/course/editcategory.php', $options, get_string('addsubcategory'), 'get');
if (has_capability('moodle/category:create', $context)) { // Print button for creating new categories
unset($options);
$options['categoryadd'] = 1;
$options['id'] = $id;
print_single_button('editcategory.php', $options, get_string('addsubcategory'), 'get');
}
echo '</div>';
}
/// Print out all the sub-categories
if ($subcategories = $DB->get_records("course_categories", array("parent"=>$category->id), "sortorder ASC")) {
if ($subcategories = $DB->get_records('course_categories', array('parent' => $category->id), 'sortorder ASC')) {
$firstentry = true;
foreach ($subcategories as $subcategory) {
if ($subcategory->visible or has_capability('moodle/course:create', $context)) {
if ($subcategory->visible || has_capability('moodle/category:viewhiddencategories', $context)) {
$subcategorieswereshown = true;
if ($firstentry) {
echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter">';
@ -253,24 +211,21 @@
echo '<tr><td style="white-space: nowrap">';
$firstentry = false;
}
$catlinkcss = $subcategory->visible ? "" : " class=\"dimmed\" ";
$catlinkcss = $subcategory->visible ? '' : ' class="dimmed" ';
echo '<a '.$catlinkcss.' href="category.php?id='.$subcategory->id.'">'.
format_string($subcategory->name).'</a><br />';
}
}
if (!$firstentry) {
echo "</td></tr></table>";
echo "<br />";
echo '</td></tr></table>';
echo '<br />';
}
}
/// Print out all the courses
unset($course); // To avoid unwanted language effects later
$courses = get_courses_page($category->id, 'c.sortorder ASC',
'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible,c.guest,c.password',
$totalcount, $page*$perpage, $perpage);
'c.id,c.sortorder,c.shortname,c.fullname,c.summary,c.visible,c.guest,c.password',
$totalcount, $page*$perpage, $perpage);
$numcourses = count($courses);
if (!$courses) {
@ -278,7 +233,7 @@
print_heading(get_string("nocoursesyet"));
}
} else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$creatorediting) {
} else if ($numcourses <= COURSE_MAX_SUMMARIES_PER_PAGE and !$page and !$editingon) {
print_box_start('courseboxes');
print_courses($category);
print_box_end();
@ -286,33 +241,31 @@
} else {
print_paging_bar($totalcount, $page, $perpage, "category.php?id=$category->id&amp;perpage=$perpage&amp;");
$strcourses = get_string("courses");
$strselect = get_string("select");
$stredit = get_string("edit");
$strdelete = get_string("delete");
$strbackup = get_string("backup");
$strrestore = get_string("restore");
$strmoveup = get_string("moveup");
$strmovedown = get_string("movedown");
$strupdate = get_string("update");
$strhide = get_string("hide");
$strshow = get_string("show");
$strsummary = get_string("summary");
$strsettings = get_string("settings");
$strassignteachers = get_string("assignteachers");
$strallowguests = get_string("allowguests");
$strrequireskey = get_string("requireskey");
$strcourses = get_string('courses');
$strselect = get_string('select');
$stredit = get_string('edit');
$strdelete = get_string('delete');
$strbackup = get_string('backup');
$strrestore = get_string('restore');
$strmoveup = get_string('moveup');
$strmovedown = get_string('movedown');
$strupdate = get_string('update');
$strhide = get_string('hide');
$strshow = get_string('show');
$strsummary = get_string('summary');
$strsettings = get_string('settings');
$strassignteachers = get_string('assignteachers');
$strallowguests = get_string('allowguests');
$strrequireskey = get_string('requireskey');
echo '<form id="movecourses" action="category.php" method="post"><div>';
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter"><tr>';
echo '<th class="header" scope="col">'.$strcourses.'</th>';
if ($creatorediting) {
if ($editingon) {
echo '<th class="header" scope="col">'.$stredit.'</th>';
if ($adminediting) {
echo '<th class="header" scope="col">'.$strselect.'</th>';
}
echo '<th class="header" scope="col">'.$strselect.'</th>';
} else {
echo '<th class="header" scope="col">&nbsp;</th>';
}
@ -336,6 +289,7 @@
$atlastpage = true;
}
$spacer = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
foreach ($courses as $acourse) {
if (isset($acourse->context)) {
$coursecontext = $acourse->context;
@ -347,24 +301,31 @@
$up = ($count > 1 || !$atfirstpage);
$down = ($count < $numcourses || !$atlastpage);
$linkcss = $acourse->visible ? "" : ' class="dimmed" ';
$linkcss = $acourse->visible ? '' : ' class="dimmed" ';
echo '<tr>';
echo '<td><a '.$linkcss.' href="view.php?id='.$acourse->id.'">'. format_string($acourse->fullname) .'</a></td>';
if ($creatorediting) {
echo "<td>";
if ($editingon) {
echo '<td>';
if (has_capability('moodle/course:update', $coursecontext)) {
echo '<a title="'.$strsettings.'" href="'.$CFG->wwwroot.'/course/edit.php?id='.
$acourse->id.'">'.
'<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" /></a> '; }
echo '<a title="'.$strsettings.'" href="'.$CFG->wwwroot.'/course/edit.php?id='.$acourse->id.'">'.
'<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" /></a> ';
} else {
echo $spacer;
}
// role assignment link
if (has_capability('moodle/role:assign', $coursecontext)) {
echo'<a title="'.get_string('assignroles', 'role').'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$coursecontext->id.'"><img src="'.$CFG->pixpath.'/i/roles.gif" class="iconsmall" alt="'.get_string('assignroles', 'role').'" /></a>';
echo '<a title="'.get_string('assignroles', 'role').'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$coursecontext->id.'">'.
'<img src="'.$CFG->pixpath.'/i/roles.gif" class="iconsmall" alt="'.get_string('assignroles', 'role').'" /></a> ';
} else {
echo $spacer;
}
if (can_delete_course($acourse->id)) {
echo '<a title="'.$strdelete.'" href="delete.php?id='.$acourse->id.'">'.
'<img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" /></a> ';
} else {
echo $spacer;
}
// MDL-8885, users with no capability to view hidden courses, should not be able to lock themselves out
@ -378,26 +339,32 @@
'&amp;perpage='.$perpage.'&amp;show='.$acourse->id.'&amp;sesskey='.$USER->sesskey.'">'.
'<img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" /></a> ';
}
} else {
echo $spacer;
}
if (has_capability('moodle/site:backup', $coursecontext)) {
echo '<a title="'.$strbackup.'" href="../backup/backup.php?id='.$acourse->id.'">'.
'<img src="'.$CFG->pixpath.'/t/backup.gif" class="iconsmall" alt="'.$strbackup.'" /></a> ';
} else {
echo $spacer;
}
if (has_capability('moodle/site:restore', $coursecontext)) {
echo '<a title="'.$strrestore.'" href="../files/index.php?id='.$acourse->id.
'&amp;wdir=/backupdata">'.
'<img src="'.$CFG->pixpath.'/t/restore.gif" class="iconsmall" alt="'.$strrestore.'" /></a> ';
} else {
echo $spacer;
}
if (has_capability('moodle/category:update', $context)) {
if (has_capability('moodle/category:manage', $context)) {
if ($up) {
echo '<a title="'.$strmoveup.'" href="category.php?id='.$category->id.'&amp;page='.$page.
'&amp;perpage='.$perpage.'&amp;moveup='.$acourse->id.'&amp;sesskey='.$USER->sesskey.'">'.
'<img src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$strmoveup.'" /></a> ';
} else {
echo '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
echo $spacer;
}
if ($down) {
@ -405,9 +372,11 @@
'&amp;perpage='.$perpage.'&amp;movedown='.$acourse->id.'&amp;sesskey='.$USER->sesskey.'">'.
'<img src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$strmovedown.'" /></a> ';
} else {
echo '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
echo $spacer;
}
$abletomovecourses = true;
} else {
echo $spacer, $spacer;
}
echo '</td>';
@ -437,19 +406,12 @@
}
if ($abletomovecourses) {
$movetocategories = array();
$notused = array();
make_categories_list($movetocategories, $notused, 'moodle/category:manage');
$movetocategories[$category->id] = get_string('moveselectedcoursesto');
echo '<tr><td colspan="3" align="right">';
echo '<br />';
unset($displaylist[$category->id]);
// loop and unset categories the user can't move into
foreach ($displaylist as $did=>$dlist) {
if (!has_capability('moodle/category:update', get_context_instance(CONTEXT_COURSECAT, $did))) {
unset($displaylist[$did]);
}
}
choose_from_menu ($displaylist, "moveto", "", get_string("moveselectedcoursesto"), "javascript: submitFormById('movecourses')");
choose_from_menu($movetocategories, 'moveto', $category->id, '', "javascript:submitFormById('movecourses')");
echo '<input type="hidden" name="id" value="'.$category->id.'" />';
echo '</td></tr>';
}
@ -459,8 +421,9 @@
echo '<br />';
}
echo '<div class="buttons">';
if (has_capability('moodle/category:update', get_context_instance(CONTEXT_SYSTEM)) and $numcourses > 1) { /// Print button to re-sort courses by name
echo '<div class="buttons">';
if (has_capability('moodle/category:manage', $context) and $numcourses > 1) {
/// Print button to re-sort courses by name
unset($options);
$options['id'] = $category->id;
$options['resort'] = 'name';
@ -468,14 +431,13 @@
print_single_button('category.php', $options, get_string('resortcoursesbyname'), 'get');
}
if (has_capability('moodle/course:create', $context)) { /// Print button to create a new course
if (has_capability('moodle/course:create', $context)) {
/// Print button to create a new course
unset($options);
$options['category'] = $category->id;
print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
}
echo '</div>';
echo '</div>';
print_course_search();

View File

@ -11,36 +11,30 @@ class delete_category_form extends moodleform {
$mform =& $this->_form;
$category = $this->_customdata;
ensure_context_subobj_present($category, CONTEXT_COURSECAT);
$this->_category = $category;
$mform->addElement('header','general', get_string('categorycurrentcontents', '', format_string($category->name)));
$displaylist = array();
$parentlist = array();
$children = array();
make_categories_list($displaylist, $parentlist);
unset($displaylist[$category->id]);
foreach ($displaylist as $catid=>$unused) {
// remove all children of $category
if (isset($parentlist[$catid]) and in_array($category->id, $parentlist[$catid])) {
$children[] = $catid;
unset($displaylist[$catid]);
continue;
}
if (!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $catid))) {
unset($displaylist[$catid]);
}
}
$notused = array();
make_categories_list($displaylist, $notused, 'moodle/course:create', $category->id);
// Check permissions, to see if it OK to give the option to delete
// the contents, rather than move elsewhere.
$candeletecontent = true;
foreach ($children as $catid) {
$context = get_context_instance(CONTEXT_COURSECAT, $catid);
if (!has_capability('moodle/category:delete', $context)) {
$tocheck = array($category);
while (!empty($tocheck)) {
$checkcat = array_pop($tocheck);
$tocheck = $tocheck + get_child_categories($checkcat->id);
if (!has_capability('moodle/category:manage', $checkcat->context)) {
$candeletecontent = false;
break;
}
}
// TODO check that the user is allowed to delete all the courses MDL-17502!
$options = array();
if ($displaylist) {
@ -48,7 +42,7 @@ class delete_category_form extends moodleform {
}
if ($candeletecontent) {
$options[1] =get_string('delete');
$options[1] = get_string('delete');
}
if (empty($options)) {

View File

@ -57,16 +57,11 @@ class course_edit_form extends moodleform {
//--------------------------------------------------------------------------------
$mform->addElement('header','general', get_string('general', 'form'));
//must have create course capability in both categories in order to move course
// Must have create course capability in both categories in order to move course
if (has_capability('moodle/course:create', $categorycontext)) {
$displaylist = array();
$parentlist = array();
make_categories_list($displaylist, $parentlist);
foreach ($displaylist as $key=>$val) {
if (!has_capability('moodle/course:create', get_context_instance(CONTEXT_COURSECAT, $key))) {
unset($displaylist[$key]);
}
}
make_categories_list($displaylist, $parentlist, 'moodle/course:create');
$mform->addElement('select', 'category', get_string('category'), $displaylist);
} else {
$mform->addElement('hidden', 'category', null);

View File

@ -1,323 +1,93 @@
<?php // $Id$
/**
* Displays a category and all its sub-categories.
* In editing mode, allows admins to move/delete/hide categories
* Page for creating or editing course category name/parent/description.
* When called with an id parameter, edits the category with that id.
* Otherwise it creates a new category with default parent from the parent
* parameter, which may be 0.
*/
require_once("../config.php");
require_once("lib.php");
require_once('../config.php');
require_once('lib.php');
require_once('editcategory_form.php');
$id = optional_param('id', 0, PARAM_INT); // Category id: if not given, show Add a Category form. If given and 'categoryupdate': show edit form
$page = optional_param('page', 0, PARAM_INT); // which page to show
$perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT); // how many per page
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$moveup = optional_param('moveup', 0, PARAM_INT);
$movedown = optional_param('movedown', 0, PARAM_INT);
$moveto = optional_param('moveto', 0, PARAM_INT);
$categoryedit = optional_param('categoryedit', -1, PARAM_BOOL); // Enables Move/Delete/Hide icons near each category in the list
$categoryadd = optional_param('categoryadd', 0, PARAM_BOOL); // Enables the Add Category form
$categoryupdate = optional_param('categoryupdate', 0, PARAM_BOOL); // Enables the Edit Category form
$resort = optional_param('resort', 0, PARAM_BOOL);
$parent = optional_param('parent', 0, PARAM_INT );
require_login();
if (!$site = get_site()) {
print_error("siteisnotdefined");
}
if ($categoryadd and !$parent) { // Show Add category form: if $id is given, it is used as the parent category
$strtitle = get_string("addnewcategory");
$context = get_context_instance(CONTEXT_SYSTEM);
$category = null;
} elseif ($categoryadd and $parent) {
$strtitle = get_string("addnewcategory");
$context = get_context_instance(CONTEXT_COURSECAT,$parent);
$category = null;
} elseif (!is_null($id) && !$categoryadd) { // Show Edit category form: $id is given as the identifier of the category being edited
$strtitle = get_string("editcategorysettings");
$context = get_context_instance(CONTEXT_COURSECAT, $id);
if (!$category = $DB->get_record("course_categories", array("id"=>$id))) {
print_error("unknowcategory");
$id = optional_param('id', 0, PARAM_INT);
if ($id) {
if (!$category = $DB->get_record('course_categories', array('id' => $id))) {
print_error('unknowcategory');
}
}
$mform = new editcategory_form('editcategory.php', compact(array('category', 'id')));
if (!empty($category)) {
$mform->set_data($category);
} elseif (!is_null($id)) {
$data = new stdClass();
$data->parent = $id;
$data->categoryadd = 1;
$mform->set_data($data);
}
if ($mform->is_cancelled()){
if (empty($category)) {
redirect($CFG->wwwroot .'/course/index.php?categoryedit=on');
require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $id));
$strtitle = get_string('editcategorysettings');
} else {
$parent = required_param('parent', PARAM_INT);
if ($parent) {
if (!$DB->record_exists('course_categories', array('id' => $parent))) {
print_error('unknowcategory');
}
$context = get_context_instance(CONTEXT_COURSECAT, $parent);
} else {
redirect($CFG->wwwroot.'/course/category.php?categoryedit=on&id='.$category->id);
}
} else if (($data = $mform->get_data())) {
$context = get_system_context();
}
$category = new stdClass();
$category->id = 0;
$category->parent = $parent;
require_capability('moodle/category:manage', $context);
$strtitle = get_string("addnewcategory");
}
$mform = new editcategory_form('editcategory.php', $category);
$mform->set_data($category);
if ($mform->is_cancelled()) {
if ($id) {
redirect($CFG->wwwroot . '/course/category.php?id=' . $id . '&categoryedit=on');
} else if ($parent) {
redirect($CFG->wwwroot .'/course/category.php?id=' . $parent . '&categoryedit=on');
} else {
redirect($CFG->wwwroot .'/course/index.php?categoryedit=on');
}
} else if ($data = $mform->get_data()) {
$newcategory = new stdClass();
$newcategory->name = $data->name;
$newcategory->name = $data->name;
$newcategory->description = $data->description;
$newcategory->parent = $data->parent; // if $id = 0, the new category will be a top-level category
$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;
theme_setup(); /// TODO: Do we really want the theme to be changed here? Doesn't look ok IMO. Eloy - 20080828
}
if (empty($category) && has_capability('moodle/category:create', $context)) { // Create a new category
$newcategory->sortorder = MAX_COURSES_IN_CATEGORY*MAX_COURSE_CATEGORIES; // put as last category in any parent cat
if (!$newcategory->id = $DB->insert_record('course_categories', $newcategory)) {
notify( "Could not insert the new category '$newcategory->name' ");
} else {
$newcategory->context = get_context_instance(CONTEXT_COURSECAT, $newcategory->id);
mark_context_dirty($newcategory->context->path);
fix_course_sortorder();
redirect('index.php?categoryedit=on');
}
} elseif (has_capability('moodle/category:update', $context)) {
if ($id) {
// Update an existing category.
$newcategory->id = $category->id;
if ($newcategory->parent != $category->parent) {
$parent_cat = $DB->get_record('course_categories', array('id'=>$newcategory->parent));
move_category($newcategory, $parent_cat); // includes sortorder fix
$parent_cat = $DB->get_record('course_categories', array('id' => $newcategory->parent));
move_category($newcategory, $parent_cat);
}
if (!$DB->update_record('course_categories', $newcategory)) {
print_error( "cannotupdatecategory", '', '', $newcategory->name);
} else {
if ($newcategory->parent == 0) {
$redirect_link = 'index.php?categoryedit=on';
} else {
$redirect_link = 'category.php?id='.$newcategory->id.'&categoryedit=on';
}
redirect($redirect_link);
}
}
fix_course_sortorder();
} else {
// Create a new category.
$newcategory->sortorder = 999;
if (!$newcategory->id = $DB->insert_record('course_categories', $newcategory)) {
print_error('cannotcreatecategory', '', '', format_string($newcategory->name));
}
$newcategory->context = get_context_instance(CONTEXT_COURSECAT, $newcategory->id);
mark_context_dirty($newcategory->context->path);
}
redirect('category.php?id='.$newcategory->id.'&categoryedit=on');
}
// If id is given, but not categoryadd or categoryupdate, we show the category with its list of subcategories
if ($id && !$categoryadd && !$categoryupdate && false) {
/* TODO implement
if ($CFG->forcelogin) {
require_login();
}
// Determine whether to allow user to see this category
if (has_capability('moodle/course:create', $context)) {
if ($categoryedit !== -1) {
$USER->categoryediting = $categoryedit;
}
$navbaritem = update_category_button($category->id);
$creatorediting = !empty($USER->categoryediting);
$adminediting = (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and $creatorediting);
} else {
if (!$category->visible) {
print_error('notavailable', 'error');
}
$navbaritem = print_course_search("", true, "navbar");
$adminediting = false;
$creatorediting = false;
}
// Resort the category if requested
if ($resort and confirm_sesskey()) {
if ($courses = get_courses($id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
// move it off the range
$count = $DB->get_record_sql('SELECT MAX(sortorder) AS max, 1
FROM {course} WHERE category=' . $category->id);
$count = $count->max + 100;
$DB->begin_sql();
foreach ($courses as $course) {
$DB->set_field('course', 'sortorder', $count, array('id'=>$course->id));
$count++;
}
$DB->commit_sql();
fix_course_sortorder($category->id);
}
}
// Print headings
$numcategories = $DB->count_records("course_categories");
$stradministration = get_string("administration");
$strcategories = get_string("categories");
$strcategory = get_string("category");
$strcourses = get_string("courses");
$navlinks = array();
$navlinks[] = array('name' => $strcategories, 'link' => 'index.php', 'type' => 'misc');
$navlinks[] = array('name' => $category->name, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
if ($creatorediting) {
if ($adminediting) {
// modify this to treat this as an admin page
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('categorymgmt');
admin_externalpage_print_header();
} else {
print_header("$site->shortname: $category->name", "$site->fullname: $strcategories", $navigation, "", "", true, $navbaritem);
}
} else {
print_header("$site->shortname: $category->name", "$site->fullname: $strcategories", $navigation, "", "", true, $navbaritem);
}
// Print button to turn editing off
if ($adminediting) {
echo '<div class="categoryediting button" align="right">'.update_category_button($category->id).'</div>';
}
// Print link to roles
if (has_capability('moodle/role:assign', $context)) {
echo '<div class="rolelink"><a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
$context->id.'">'.get_string('assignroles','role').'</a></div>';
}
// Print the category selector
$displaylist = array();
$parentlist = array();
make_categories_list($displaylist, $parentlist, "");
echo '<div class="categorypicker">';
popup_form('category.php?id=', $displaylist, 'switchcategory', $category->id, '', '', '', false, 'self', $strcategories.':');
echo '</div>';
// Print current category description
if ($category->description) {
print_box_start();
print_heading(get_string('description'));
echo $category->description;
print_box_end();
}
// Editing functions
if ($creatorediting) {
// Move a specified category to a new category
if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) { // Some courses are being moved
// user must have category update in both cats to perform this
require_capability('moodle/category:update', $context);
require_capability('moodle/category:update', get_context_instance(CONTEXT_COURSECAT, $moveto));
if (!$destcategory = $DB->get_record("course_categories", array("id"=>$data->moveto))) {
pritn_error("unknowcategory");
}
// TODO function to move the category
}
// Hide or show a category
if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
require_capability('moodle/category:visibility', $context);
if (!empty($hide)) {
$category = $DB->get_record("course_categories", array("id"=>$hide));
$visible = 0;
} else {
$category = $DB->get_record("course_categories", array("id"=>$show));
$visible = 1;
}
if ($category) {
if (! $DB->set_field("course_categories", "visible", $visible, array("id"=>$category->id))) {
notify("Could not update that category!");
}
}
}
// Move a category up or down
if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
require_capability('moodle/category:update', $context);
$movecategory = NULL;
$swapcategory = NULL;
// TODO something like fix_course_sortorder() ?
// we are going to need to know the range
$max = $DB->get_record_sql('SELECT MAX(sortorder) AS max, 1 FROM {course_categories} WHERE id=' . $category->id);
$max = $max->max + 100;
if (!empty($moveup)) {
$movecategory = $DB->get_record('course_categories', array('id'=>$moveup));
$swapcategory = $DB->get_record('course_categories',
array('category'=>$category->id,
'sortorder'=>$movecategory->sortorder - 1));
} else {
$movecategory = $DB->get_record('course_categories', array('id'=>$movedown));
$swapcategory = $DB->get_record('course_categories',
array('category'=> $category->id,
'sortorder'=>$movecategory->sortorder + 1));
}
if ($swapcourse and $movecourse) { // Renumber everything for robustness
$DB->begin_sql();
if (!( $DB->set_field("course", "sortorder", $max, aray("id"=>$swapcourse->id))
&& $DB->set_field("course", "sortorder", $swapcourse->sortorder, array("id"=>$movecourse->id))
&& $DB->set_field("course", "sortorder", $movecourse->sortorder, array("id"=>$swapcourse->id))
)) {
notify("Could not update that course!");
}
$DB->commit_sql();
}
}
} // End of editing stuff
// Print out all the sub-categories
if ($subcategories = $DB->get_records("course_categories", array("parent"=>$category->id), "sortorder ASC")) {
$firstentry = true;
foreach ($subcategories as $subcategory) {
if ($subcategory->visible or has_capability('moodle/course:create', $context)) {
$subcategorieswereshown = true;
if ($firstentry) {
echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter">';
echo '<tr><th scope="col">'.get_string('subcategories').'</th></tr>';
echo '<tr><td style="white-space: nowrap">';
$firstentry = false;
}
$catlinkcss = $subcategory->visible ? "" : " class=\"dimmed\" ";
echo '<a '.$catlinkcss.' href="category.php?id='.$subcategory->id.'">'.
format_string($subcategory->name).'</a><br />';
}
}
if (!$firstentry) {
echo "</td></tr></table>";
echo "<br />";
}
}
// print option to add a subcategory
if (has_capability('moodle/category:create', $context) && $creatorediting) {
$cat->id = $id;
$mform->set_data($cat);
$mform->display();
}
*/
}
// Print the form
$site = get_site();
$straddnewcategory = get_string("addnewcategory");
$stradministration = get_string("administration");
$strcategories = get_string("categories");
$straddnewcategory = get_string('addnewcategory');
$stradministration = get_string('administration');
$strcategories = get_string('categories');
$navlinks = array();
if (!empty($category->name)) {
if ($id) {
$navlinks[] = array('name' => $strtitle,
'link' => null,
'type' => 'misc');
@ -333,8 +103,8 @@ if (!empty($category->name)) {
$navlinks[] = array('name' => $straddnewcategory,
'link' => null,
'type' => 'misc');
$title = "$site->shortname: $straddnewcategory";
$fullname = $site->fullname;
$title = "$SITE->shortname: $straddnewcategory";
$fullname = $SITE->fullname;
}
$navigation = build_navigation($navlinks);

View File

@ -6,15 +6,24 @@ class editcategory_form extends moodleform {
function definition() {
global $CFG;
$mform =& $this->_form;
$category = $this->_customdata;
// get list of categories to use as parents, with site as the first one
$options = array(get_string('top'));
$parents = array();
make_categories_list($options, $parents);
if ($category->id) {
// Editing an existing category.
make_categories_list($options, $parents, 'moodle/category:manage', $category->id);
$strsubmit = get_string('savechanges');
} else {
// Making a new category
make_categories_list($options, $parents, 'moodle/category:manage');
$strsubmit = get_string('createcategory');
}
$mform->addElement('select', 'parent', get_string('parentcategory'), $options);
$mform->addElement('text', 'name', get_string('categoryname'), array('size'=>'30'));
$mform->addRule('name', get_string('required'), 'required', null);
$mform->addElement('text', 'name', get_string('categoryname'), array('size'=>'30'));
$mform->addRule('name', get_string('required'), 'required', null);
$mform->addElement('htmleditor', 'description', get_string('description'));
$mform->setType('description', PARAM_RAW);
if (!empty($CFG->allowcategorythemes)) {
@ -24,11 +33,12 @@ class editcategory_form extends moodleform {
$mform->addElement('select', 'theme', get_string('forcetheme'), $themes);
}
$mform->setHelpButton('description', array('writing', 'richtext2'), false, 'editorhelpbutton');
$mform->addElement('hidden', 'id', null);
$mform->addElement('hidden', 'categoryadd', 0);
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$this->add_action_buttons(true, get_string('savechanges'));
$mform->setDefault('id', $category->id);
$this->add_action_buttons(true, $strsubmit);
}
}
?>

View File

@ -14,18 +14,17 @@
$moveup = optional_param('moveup',0,PARAM_INT);
$movedown = optional_param('movedown',0,PARAM_INT);
$sysctx = get_context_instance(CONTEXT_SYSTEM);
$context = $sysctx;
if ($CFG->forcelogin) {
require_login();
}
if (!$site = get_site()) {
print_error('siteisnotdefined', 'debug');
}
if ($CFG->forcelogin) {
require_login();
}
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
if (has_capability('moodle/category:update', $sysctx)) {
if (update_category_button()) {
if ($categoryedit !== -1) {
$USER->categoryediting = $categoryedit;
}
@ -44,11 +43,9 @@
/// Unless it's an editing admin, just print the regular listing of courses/categories
if (!$adminediting) {
/// Print form for creating new categories
/// Print form for creating new categories
$countcategories = $DB->count_records('course_categories');
if ($countcategories > 1 || ($countcategories == 1 && $DB->count_records('course') > 200)) {
@ -58,7 +55,7 @@
$navlinks = array();
$navlinks[] = array('name'=>$strcategories,'link'=>'','type'=>'misc');
$navigation = build_navigation($navlinks);
print_header("$site->shortname: $strcategories", $strcourses, $navigation, '', '', true, update_categories_button());
print_header("$site->shortname: $strcategories", $strcourses, $navigation, '', '', true, update_category_button());
print_heading($strcategories);
echo skip_main_destination();
print_box_start('categorybox');
@ -69,45 +66,44 @@
$strfulllistofcourses = get_string('fulllistofcourses');
print_header("$site->shortname: $strfulllistofcourses", $strfulllistofcourses,
build_navigation(array(array('name'=>$strfulllistofcourses, 'link'=>'','type'=>'misc'))),
'', '', true, update_categories_button());
'', '', true, update_category_button());
echo skip_main_destination();
print_box_start('courseboxes');
print_courses(0);
print_box_end();
}
/// I am not sure this context in the next has_capability call is correct.
if (isloggedin() and !isguest() and !has_capability('moodle/course:create', $sysctx) and $CFG->enablecourserequests) { // Print link to request a new course
echo '<div class="buttons">';
if ($CFG->enablecourserequests and isloggedin() and !isguest() and !has_capability('moodle/course:create', $systemcontext)) {
/// Print link to request a new course
print_single_button('request.php', NULL, get_string('courserequest'), 'get');
}
if (has_capability('moodle/course:create', $sysctx)) { // Print link to create a new course
if (has_capability('moodle/course:create', $systemcontext)) {
/// Print link to create a new course
/// Get the 1st available category
$options = array('category' => $DB->get_field('course_categories', 'id', array('parent'=>'0')));
$options = array('category' => $CFG->defaultrequestcategory);
print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
}
if (has_capability('moodle/site:approvecourse', $sysctx) and !empty($CFG->enablecourserequests)) {
if (has_capability('moodle/site:approvecourse', $systemcontext) and !empty($CFG->enablecourserequests)) {
print_single_button('pending.php',NULL, get_string('coursespending'),'get');
}
echo '</div>';
print_footer();
exit;
}
/// Everything else is editing on mode.
/// From now on is all the admin/course creator functions
/// Delete a category if necessary
/// Delete a category.
if (!empty($delete) and confirm_sesskey()) {
require_once('delete_category_form.php');
if (!$deletecat = $DB->get_record('course_categories', array('id'=>$delete))) {
print_error('invalidcategoryid');
}
$context = get_context_instance(CONTEXT_COURSECAT, $delete);
require_capability('moodle/category:manage', $context);
require_capability('moodle/category:manage', get_category_or_system_context($deletecat->parent));
$heading = get_string('deletecategory', '', format_string($deletecat->name));
$context = get_context_instance(CONTEXT_COURSECAT, $delete);
require_capability('moodle/category:delete', $context);
require_once('delete_category_form.php');
$mform = new delete_category_form(null, $deletecat);
$mform->set_data(array('delete'=>$delete));
@ -124,7 +120,7 @@
'generalbox boxwidthnormal boxaligncenter');
}
$mform->display();
print_footer();
admin_externalpage_print_footer();
exit();
}
@ -137,9 +133,14 @@
category_delete_move($deletecat, $data->newparent, true);
}
// If we deleted $CFG->defaultrequestcategory, make it point somewhere else.
if ($delete == $CFG->defaultrequestcategory) {
set_config('defaultrequestcategory', get_field('course_categories', 'MIN(id)', 'parent', 0));
}
print_continue('index.php');
print_footer();
admin_externalpage_print_footer();
die;
}
@ -147,7 +148,6 @@
print_category_edit_header();
print_heading($strcategories);
/// Create a default category if necessary
if (!$categories = get_categories()) { /// No category yet!
// Try and make one
@ -160,21 +160,20 @@
mark_context_dirty('/'.SYSCONTEXTID);
}
/// Move a category to a new parent if required
if (!empty($move) and ($moveto>=0) and confirm_sesskey()) {
if ($tempcat = $DB->get_record('course_categories', array('id'=>$move))) {
if ($tempcat->parent != $moveto) {
$newp = $DB->get_record('course_categories', array('id'=>$moveto));
if (! move_category($tempcat, $newp)) {
notify('Could not update that category!');
if (!empty($move) and ($moveto >= 0) and confirm_sesskey()) {
if ($cattomove = $DB->get_record('course_categories', array('id'=>$move))) {
require_capability('moodle/category:manage', get_category_or_system_context($cattomove->parent));
if ($cattomove->parent != $moveto) {
$newparent = $DB->get_record('course_categories', array('id'=>$moveto));
require_capability('moodle/category:manage', get_category_or_system_context($moveto));
if (!move_category($cattomove, $newparent)) {
print_error('cannotupdatecategory', '', '', format_string($cattomove->name));
}
}
}
}
/// Hide or show a category
if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
if (!empty($hide)) {
@ -184,31 +183,31 @@
$tempcat = $DB->get_record('course_categories', array('id'=>$show));
$visible = 1;
}
require_capability('moodle/category:manage', get_category_or_system_context($tempcat->parent));
if ($tempcat) {
if (!$DB->set_field('course_categories', 'visible', $visible, array('id'=>$tempcat->id))) {
notify('Could not update that category!');
print_error('cannotupdatecategory', '', '', format_string($tempcat->name));
}
if (!$DB->set_field('course', 'visible', $visible, array('category'=>$tempcat->id))) {
notify('Could not hide/show any courses in this category !');
if (!$DB->set_field('course', 'visible', $visible, array('category' => $tempcat->id))) {
print_error('cannotshowhidecoursesincategory', '', '', format_string($tempcat->name));
}
}
}
/// 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 ASC', '*', 0, 1)) {
$swapcategory = reset($swapcategory);
}
}
} else {
require_capability('moodle/category:manage', get_context_instance(CONTEXT_COURSECAT, $movedown));
if ($movecategory = $DB->get_record('course_categories', array('id'=>$movedown))) {
if ($swapcategory = $DB->get_records_select('course_categories', "sortorder>? AND parent=?", array($movecategory->sortorder, $movecategory->parent), 'sortorder ASC', '*', 0, 1)) {
$swapcategory = reset($swapcategory);
@ -224,11 +223,7 @@
fix_course_sortorder();
}
/// This should not be needed anymore
//fix_course_sortorder();
/// Print out the categories with all the knobs
$strcategories = get_string('categories');
$strcourses = get_string('courses');
$strmovecategoryto = get_string('movecategoryto');
@ -238,7 +233,7 @@
$parentlist = array();
$displaylist[0] = get_string('top');
make_categories_list($displaylist, $parentlist, '');
make_categories_list($displaylist, $parentlist);
echo '<table class="generalbox editcourse boxaligncenter"><tr class="header">';
echo '<th class="header" scope="col">'.$strcategories.'</th>';
@ -253,52 +248,39 @@
echo '<div class="buttons">';
if (!empty($category->id)) {
// Print link to create a new course in current category
if (has_capability('moodle/course:create', $context)) {
$options = array();
$options['category'] = $category->id;
print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
}
}else{
if (has_capability('moodle/course:create', $sysctx)) {
// print create course link to first category
$options = array();
$options = array('category' => $DB->get_field('course_categories', 'id', array('parent'=>'0')));
print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
}
if (has_capability('moodle/course:create', $systemcontext)) {
// print create course link to first category
$options = array();
$options = array('category' => $CFG->defaultrequestcategory);
print_single_button('edit.php', $options, get_string('addnewcourse'), 'get');
}
// Print button for creating new categories
if (has_capability('moodle/category:create', $context)) {
unset($options);
if (!empty($category->id)) {
$options['id'] = $category->id;
} else {
$options['id'] = 0;
}
$options['categoryadd'] = 1;
if (has_capability('moodle/category:manage', $systemcontext)) {
$options = array();
$options['parent'] = 0;
print_single_button('editcategory.php', $options, get_string('addnewcategory'), 'get');
}
if (has_capability('moodle/site:approvecourse', $sysctx) and !empty($CFG->enablecourserequests)) {
if (has_capability('moodle/site:approvecourse', $systemcontext) and !empty($CFG->enablecourserequests)) {
print_single_button('pending.php',NULL, get_string('coursespending'), 'get');
}
// admin page does not allow custom buttons in the navigation bar
echo '<div class="singlebutton">';
echo update_categories_button();
echo update_category_button();
echo '</div></div>';
print_footer();
admin_externalpage_print_footer();
function print_category_edit($category, $displaylist, $parentslist, $depth=-1, $up=false, $down=false) {
/// Recursive function to print all the categories ready for editing
global $CFG, $USER;
static $str = '';
static $str = NULL;
if (empty($str)) {
if (is_null($str)) {
$str = new stdClass;
$str->edit = get_string('edit');
$str->delete = get_string('delete');
$str->moveup = get_string('moveup');
@ -306,9 +288,10 @@ function print_category_edit($category, $displaylist, $parentslist, $depth=-1, $
$str->edit = get_string('editthiscategory');
$str->hide = get_string('hide');
$str->show = get_string('show');
$str->spacer = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
}
if ($category) {
if (!empty($category)) {
if (!isset($category->context)) {
$category->context = get_context_instance(CONTEXT_COURSECAT, $category->id);
@ -328,17 +311,13 @@ function print_category_edit($category, $displaylist, $parentslist, $depth=-1, $
echo '<td class="icons">'; /// Print little icons
if (has_capability('moodle/category:update', $category->context)) {
echo '<a title="'.$str->edit.'" href="editcategory.php?id='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
if (has_capability('moodle/category:manage', $category->context)) {
echo '<a title="'.$str->edit.'" href="editcategory.php?id='.$category->id.'"><img'.
' src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$str->edit.'" /></a> ';
}
if (has_capability('moodle/category:delete', $category->context)) {
echo '<a title="'.$str->delete.'" href="index.php?delete='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$str->delete.'" /></a> ';
}
if (has_capability('moodle/category:visibility', $category->context)) {
if (!empty($category->visible)) {
echo '<a title="'.$str->hide.'" href="index.php?hide='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$str->hide.'" /></a> ';
@ -346,27 +325,33 @@ function print_category_edit($category, $displaylist, $parentslist, $depth=-1, $
echo '<a title="'.$str->show.'" href="index.php?show='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$str->show.'" /></a> ';
}
}
if ($up) {
echo '<a title="'.$str->moveup.'" href="index.php?moveup='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$str->moveup.'" /></a> ';
}
if ($down) {
echo '<a title="'.$str->movedown.'" href="index.php?movedown='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$str->movedown.'" /></a> ';
if ($up) {
echo '<a title="'.$str->moveup.'" href="index.php?moveup='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$str->moveup.'" /></a> ';
} else {
echo $str->spacer;
}
if ($down) {
echo '<a title="'.$str->movedown.'" href="index.php?movedown='.$category->id.'&amp;sesskey='.sesskey().'"><img'.
' src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$str->movedown.'" /></a> ';
} else {
echo $str->spacer;
}
}
echo '</td>';
echo '<td align="left">';
$tempdisplaylist = $displaylist;
unset($tempdisplaylist[$category->id]);
foreach ($parentslist as $key => $parents) {
if (in_array($category->id, $parents)) {
unset($tempdisplaylist[$key]);
if (has_capability('moodle/category:manage', $category->context)) {
$tempdisplaylist = $displaylist;
unset($tempdisplaylist[$category->id]);
foreach ($parentslist as $key => $parents) {
if (in_array($category->id, $parents)) {
unset($tempdisplaylist[$key]);
}
}
popup_form ("index.php?move=$category->id&amp;sesskey=$USER->sesskey&amp;moveto=", $tempdisplaylist, "moveform$category->id", $category->parent, '', '', '', false);
}
popup_form ("index.php?move=$category->id&amp;sesskey=$USER->sesskey&amp;moveto=", $tempdisplaylist, "moveform$category->id", $category->parent, '', '', '', false);
echo '</td>';
echo '</tr>';
} else {
@ -396,13 +381,8 @@ function print_category_edit_header() {
global $CFG;
global $SITE;
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('coursemgmt');
admin_externalpage_print_header();
} else {
print_header("$SITE->shortname:". get_string('categories'), get_string('courses'),
build_navigation(array(array('name'=>get_string('categories'),'link'=>'','type'=>'misc'))), '', '', true, update_categories_button());
}
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('coursemgmt');
admin_externalpage_print_header();
}
?>

View File

@ -1625,6 +1625,21 @@ function print_section_add_menus($course, $section, $modnames, $vertical=false,
}
}
/**
* Return the course category context for the category with id $categoryid, except
* that if $categoryid is 0, return the system context.
*
* @param integer $categoryid a category id or 0.
* @return object the corresponding context
*/
function get_category_or_system_context($categoryid) {
if ($categoryid) {
return get_context_instance(CONTEXT_COURSECAT, $categoryid);
} else {
return get_context_instance(CONTEXT_SYSTEM);
}
}
/**
* Rebuilds the cached list of course activities stored in the database
* @param int $courseid - id of course to rebuil, empty means all
@ -1676,10 +1691,13 @@ function rebuild_course_cache($courseid=0, $clearonly=false) {
}
/**
* Returns an array of the children categories for the given category
* ID by caching all of the categories in a static hash
* Gets the child categories of a given coures category. Uses a static cache
* to make repeat calls efficient.
*
* @param unknown_type $parentid the id of a course category.
* @return array all the child course categories.
*/
function get_child_categories($parent) {
function get_child_categories($parentid) {
static $allcategories = null;
// only fill in this variable the first time
@ -1695,19 +1713,51 @@ function get_child_categories($parent) {
}
}
if (empty($allcategories[$parent])) {
if (empty($allcategories[$parentid])) {
return array();
} else {
return $allcategories[$parent];
return $allcategories[$parentid];
}
}
/**
* Given an empty array, this function recursively travels the
* categories, building up a nice list for display. It also makes
* an array that list all the parents for each category.
* This function recursively travels the categories, building up a nice list
* for display. It also makes an array that list all the parents for each
* category.
*
* For example, if you have a tree of categories like:
* Miscellaneous (id = 1)
* Subcategory (id = 2)
* Sub-subcategory (id = 4)
* Other category (id = 3)
* Then after calling this function you will have
* $list = array(1 => 'Miscellaneous', 2 => 'Miscellaneous / Subcategory',
* 4 => 'Miscellaneous / Subcategory / Sub-subcategory',
* 3 => 'Other category');
* $parents = array(2 => array(1), 4 => array(1, 2));
*
* If you specify $requiredcapability, then only categories where the current
* user has that capability will be added to $list, although all categories
* will still be added to $parents, and if you only have $requiredcapability
* in a child category, not the parent, then the child catgegory will still be
* included.
*
* If you specify the option $excluded, then that category, and all its children,
* are omitted from the tree. This is useful when you are doing something like
* moving categories, where you do not want to allow people to move a category
* to be the child of itself.
*
* @param array $list For output, accumulates an array categoryid => full category path name
* @param array $parents For output, accumulates an array categoryid => list of parent category ids.
* @param string $requiredcapability if given, only categories where the current
* user has this capability will be added to $list.
* @param integer $excludeid Omit this category and its children from the lists built.
* @param object $category Build the tree starting at this category - otherwise starts at the top level.
* @param string $path For internal use, as part of recursive calls.
*/
function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
function make_categories_list(&$list, &$parents, $requiredcapability = '',
$excludeid = 0, $category = NULL, $path = "") {
// initialize the arrays if needed
if (!is_array($list)) {
$list = array();
@ -1716,18 +1766,34 @@ function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
$parents = array();
}
if ($category) {
if (empty($category)) {
// Start at the top level.
$category = new stdClass;
$category->id = 0;
} else {
// This is the excluded category, don't include it.
if ($excludeid > 0 && $excludeid == $category->id) {
return;
}
// Update $path.
if ($path) {
$path = $path.' / '.format_string($category->name);
} else {
$path = format_string($category->name);
}
$list[$category->id] = $path;
} else {
$category->id = 0;
// Add this category to $list, if the permissions check out.
if ($requiredcapability) {
ensure_context_subobj_present($category, CONTEXT_COURSECAT);
}
if (!$requiredcapability || has_capability($requiredcapability, $category->context)) {
$list[$category->id] = $path;
}
}
if ($categories = get_child_categories($category->id)) { // Print all the children recursively
// Add all the children recursively, while updating the parents array.
if ($categories = get_child_categories($category->id)) {
foreach ($categories as $cat) {
if (!empty($category->id)) {
if (isset($parents[$category->id])) {
@ -1735,7 +1801,7 @@ function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
}
$parents[$cat->id][] = $category->id;
}
make_categories_list($list, $parents, $cat, $path);
make_categories_list($list, $parents, $requiredcapability, $excludeid, $cat, $path);
}
}
}
@ -1745,7 +1811,7 @@ function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
* Recursive function to print out all the categories in a nice format
* with or without courses included
*/
function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $files = true) {
function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $showcourses = true) {
global $CFG;
if (isset($CFG->max_category_depth) && ($depth >= $CFG->max_category_depth)) {
@ -1757,8 +1823,8 @@ function print_whole_category_list($category=NULL, $displaylist=NULL, $parentsli
}
if ($category) {
if ($category->visible or has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM))) {
print_category_info($category, $depth, $files);
if ($category->visible or has_capability('moodle/category:viewhiddencategories', get_context_instance(CONTEXT_SYSTEM))) {
print_category_info($category, $depth, $showcourses);
} else {
return; // Don't bother printing children of invisible categories
}
@ -1781,7 +1847,7 @@ function print_whole_category_list($category=NULL, $displaylist=NULL, $parentsli
$down = $last ? false : true;
$first = false;
print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $files);
print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $showcourses);
}
}
}
@ -1807,7 +1873,7 @@ function make_categories_options() {
* Prints the category info in indented fashion
* This function is only used by print_whole_category_list() above
*/
function print_category_info($category, $depth, $files = false) {
function print_category_info($category, $depth, $showcourses = false) {
global $CFG, $DB;
static $strallowguests, $strrequireskey, $strsummary;
@ -1820,7 +1886,7 @@ function print_category_info($category, $depth, $files = false) {
$catlinkcss = $category->visible ? '' : ' class="dimmed" ';
$coursecount = $DB->count_records('course') <= FRONTPAGECOURSELIMIT;
if ($files and $coursecount) {
if ($showcourses and $coursecount) {
$catimage = '<img src="'.$CFG->pixpath.'/i/course.gif" alt="" />';
} else {
$catimage = "&nbsp;";
@ -1829,7 +1895,7 @@ function print_category_info($category, $depth, $files = false) {
echo "\n\n".'<table class="categorylist">';
$courses = get_courses($category->id, 'c.sortorder ASC', 'c.id,c.sortorder,c.visible,c.fullname,c.shortname,c.password,c.summary,c.guest,c.cost,c.currency');
if ($files and $coursecount) {
if ($showcourses and $coursecount) {
echo '<tr>';
@ -1900,7 +1966,42 @@ function print_category_info($category, $depth, $files = false) {
echo '</table>';
}
/**
* 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);
}
/**
* Category is 0 (for all courses) or an object

View File

@ -72,7 +72,7 @@
$displaylist = array();
$parentlist = array();
make_categories_list($displaylist, $parentlist, "");
make_categories_list($displaylist, $parentlist);
$strcourses = get_string("courses");
$strsearch = get_string("search");
@ -258,7 +258,7 @@
// this is ok since this will get inherited from course category context
// if it is set
if (has_capability('moodle/category:update', $coursecontext)) {
if (has_capability('moodle/category:manage', $coursecontext)) {
echo "<input type=\"checkbox\" name=\"c$course->id\" />\n";
} else {
echo "<input type=\"checkbox\" name=\"c$course->id\" disabled=\"disabled\" />\n";

View File

@ -127,6 +127,7 @@ $string['cannotsetupcategory'] = 'Serious error! Could not set up a default cour
$string['cannotsetupcapforplugin'] = 'Could not set up the capabilities for $a';
$string['cannotsetupcapformod'] = 'Could not set up the capabilities for $a';
$string['cannotsetupsite'] = 'Serious error! Could not set up the site!';
$string['cannotshowhidecoursesincategory'] = 'Cannot show/hide the courses in category $a.';
$string['cannotunzipfile'] = 'Cannot unzip file';
$string['cannotupgradeblock'] = 'Upgrade of blocks system failed! (Could not update version in config table.)';
$string['cannotupgradecaps'] = 'Had difficulties upgrading the core capabilities for the Roles system';
@ -211,6 +212,7 @@ $string['errorcreatingrole'] = 'Error creating role';
$string['erroronline'] = 'Error on line $a';
$string['errorreadingfile'] = 'Error reading file \"$a\"';
$string['errorunzippingfiles'] = 'Error unzipping files';
$string['errorupdatingcoursevisibility'] = 'Error updating the course visibility';
$string['errorsettinguserpref'] = 'Error setting user preference';
$string['expiredkey'] = 'Expired key';
$string['failtoloadblocks'] = 'One or more blocks are registered in the database, but they all failed to load!';

View File

@ -329,6 +329,7 @@ $string['courseupdates'] = 'Course updates';
$string['courseuploadlimit'] = 'Course upload limit';
$string['create'] = 'Create';
$string['createaccount'] = 'Create my new account';
$string['createcategory'] = 'Create category';
$string['createfolder'] = 'Create a folder in $a';
$string['createuserandpass'] = 'Choose your username and password';
$string['createziparchive'] = 'Create zip archive';

View File

@ -35,7 +35,9 @@ $string['capabilities'] = 'Capabilities';
$string['capability'] = 'Capability';
$string['category:create'] = 'Create categories';
$string['category:delete'] = 'Delete categories';
$string['category:manage'] = 'Manage categories';
$string['category:update'] = 'Update categories';
$string['category:viewhiddencategories'] = 'See hidden categories';
$string['category:visibility'] = 'See hidden categories';
$string['checkglobalpermissions'] = 'Check system permissions';
$string['checkpermissions'] = 'Check permissions';

View File

@ -5848,6 +5848,37 @@ function make_context_subobj($rec) {
return $rec;
}
/**
* Do some basic, quick checks to see whether $rec->context looks like a
* valid context object.
*
* @param object $rec a think that has a context, for example a course,
* course category, course modules, etc.
* @param integer $contextlevel the type of thing $rec is, one of the CONTEXT_... constants.
* @return boolean whether $rec->context looks like the correct context object
* for this thing.
*/
function is_context_subobj_valid($rec, $contextlevel) {
return isset($rec->context) && isset($rec->context->id) &&
isset($rec->context->path) && isset($rec->context->depth) &&
isset($rec->context->contextlevel) && isset($rec->context->instanceid) &&
$rec->context->contextlevel == $contextlevel && $rec->context->instanceid == $rec->id;
}
/**
* When you have a record (for example a $category, $course, $user or $cm that may,
* or may not, have come from a place that does make_context_subobj, you can use
* this method to ensure that $rec->context is present and correct before you continue.
*
* @param object $rec a thing that has an associated context.
* @param integer $contextlevel the type of thing $rec is, one of the CONTEXT_... constants.
*/
function ensure_context_subobj_present(&$rec, $contextlevel) {
if (!is_context_subobj_valid($rec, $contextlevel)) {
$rec->context = get_context_instance($contextlevel, $rec->id);
}
}
/**
* Fetch recent dirty contexts to know cheaply whether our $USER->access
* is stale and needs to be reloaded.

View File

@ -941,14 +941,14 @@ function get_my_courses($userid, $sort='visible DESC,sortorder ASC', $fields=NUL
//
// Perhaps it's actually visible to $USER
// check moodle/category:visibility
// check moodle/category:viewhiddencategories
//
// The name isn't obvious, but the description says
// "See hidden categories" so the user shall see...
// But also check if the allowvisiblecoursesinhiddencategories setting is true, and check for course visibility
if ($viscat === false) {
$catctx = $cats[$courses[$n]->category]->context;
if (has_capability('moodle/category:visibility', $catctx, $USER->id)) {
if (has_capability('moodle/category:viewhiddencategories', $catctx, $USER->id)) {
$vcatpaths[$courses[$n]->categorypath] = true;
$viscat = true;
} elseif ($CFG->allowvisiblecoursesinhiddencategories && $courses[$n]->visible == true) {
@ -1160,7 +1160,7 @@ function get_categories($parent='none', $sort=NULL, $shallow=true) {
if( $rs = $DB->get_recordset_sql($sql, $params) ){
foreach($rs as $cat) {
$cat = make_context_subobj($cat);
if ($cat->visible || has_capability('moodle/category:visibility',$cat->context)) {
if ($cat->visible || has_capability('moodle/category:viewhiddencategories',$cat->context)) {
$categories[$cat->id] = $cat;
}
}
@ -1332,7 +1332,7 @@ function fix_course_sortorder() {
}
// now make sure that sortorders in course table are withing the category sortorder ranges
$sql = "SELECT cc.id, cc.sortorder
$sql = "SELECT DISTINCT cc.id, cc.sortorder
FROM {course_categories} cc
JOIN {course} c ON c.category = cc.id
WHERE c.sortorder < cc.sortorder OR c.sortorder > cc.sortorder + ".MAX_COURSES_IN_CATEGORY;
@ -2184,7 +2184,7 @@ function print_object($object) {
* we'll save a dbquery
*
* - If we return false, you'll still need to check if
* the user can has the 'moodle/category:visibility'
* the user can has the 'moodle/category:viewhiddencategories'
* capability...
*
* - Will generate 2 DB calls.

View File

@ -452,7 +452,11 @@ $moodle_capabilities = array(
)
),
'moodle/category:create' => array(
// Create, update and delete course categories. (Deleting a course category
// does not let you delete the courses it contains, unless you also have
// moodle/course: delete.) Creating and deleting requires this permission in
// the parent category.
'moodle/category:manage' => array(
'riskbitmask' => RISK_XSS,
@ -460,38 +464,19 @@ $moodle_capabilities = array(
'contextlevel' => CONTEXT_COURSECAT,
'legacy' => array(
'admin' => CAP_ALLOW
)
),
'clonepermissionsfrom' => 'moodle/category:update'
),
'moodle/category:delete' => array(
'moodle/category:viewhiddencategories' => array(
'riskbitmask' => RISK_DATALOSS,
'captype' => 'write',
'captype' => 'read',
'contextlevel' => CONTEXT_COURSECAT,
'legacy' => array(
'coursecreator' => CAP_ALLOW,
'admin' => CAP_ALLOW
)
),
'moodle/category:update' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSECAT,
'legacy' => array(
'admin' => CAP_ALLOW
)
),
'moodle/category:visibility' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_COURSECAT,
'legacy' => array(
'admin' => CAP_ALLOW
)
),
'clonepermissionsfrom' => 'moodle/category:visibility'
),
'moodle/course:create' => array(

View File

@ -5290,63 +5290,6 @@ function update_module_button($moduleid, $courseid, $string) {
}
}
/**
* Prints the editing button on a category page
*
* @uses $CFG
* @uses $USER
* @param int $categoryid ?
* @return string
* @todo Finish documenting this function
*/
function update_category_button($categoryid) {
global $CFG, $USER;
if (has_capability('moodle/category:update', get_context_instance(CONTEXT_COURSECAT, $categoryid))) {
if (!empty($USER->categoryediting)) {
$string = get_string('turneditingoff');
$edit = 'off';
} else {
$string = get_string('turneditingon');
$edit = 'on';
}
return "<form $CFG->frametarget method=\"get\" action=\"$CFG->wwwroot/course/category.php\">".
'<div>'.
"<input type=\"hidden\" name=\"id\" value=\"$categoryid\" />".
"<input type=\"hidden\" name=\"categoryedit\" value=\"$edit\" />".
"<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />".
"<input type=\"submit\" value=\"$string\" /></div></form>";
}
}
/**
* Prints the editing button on categories listing
*
* @uses $CFG
* @uses $USER
* @return string
*/
function update_categories_button() {
global $CFG, $USER;
if (has_capability('moodle/category:update', get_context_instance(CONTEXT_SYSTEM))) {
if (!empty($USER->categoryediting)) {
$string = get_string('turneditingoff');
$categoryedit = 'off';
} else {
$string = get_string('turneditingon');
$categoryedit = 'on';
}
return "<form $CFG->frametarget method=\"get\" action=\"$CFG->wwwroot/course/index.php\">".
'<div>'.
'<input type="hidden" name="categoryedit" value="'. $categoryedit .'" />'.
'<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />'.
'<input type="submit" value="'. $string .'" /></div></form>';
}
}
/**
* Prints the editing button on search results listing
* For bulk move courses to another category

View File

@ -2229,10 +2229,12 @@ body#course-category .addcategory {
padding: 10px;
}
body#course-index .buttons .singlebutton,
body#course-category .buttons .singlebutton {
display: inline;
}
body#course-index .buttons,
body#course-category .buttons {
text-align: center;
margin-bottom: 15px;
@ -2329,6 +2331,7 @@ body#course-info .generalbox.info {
#coursesearch,
#coursesearch2 {
margin-top: 1em;
text-align:center;
}

View File

@ -6,7 +6,7 @@
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
$version = 2008120100; // YYYYMMDD = date of the last version bump
$version = 2008120400; // YYYYMMDD = date of the last version bump
// XX = daily increments
$release = '2.0 dev (Build: 20081204)'; // Human-friendly version name