From deb65cedc437126f3420a2fcebcf184e7a83e570 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Thu, 21 Feb 2013 10:46:52 +1100 Subject: [PATCH] MDL-38147 deprecated category_delete_move(), category_delete_full(), change usage to coursecat --- course/delete_category_form.php | 138 +++++++++++--------------------- course/externallib.php | 30 +++---- course/lib.php | 109 +------------------------ course/manage.php | 23 +++--- lib/deprecatedlib.php | 44 ++++++++++ lib/upgrade.txt | 3 +- 6 files changed, 122 insertions(+), 225 deletions(-) diff --git a/course/delete_category_form.php b/course/delete_category_form.php index ebd1678ec08..f76655e18c1 100644 --- a/course/delete_category_form.php +++ b/course/delete_category_form.php @@ -13,61 +13,18 @@ class delete_category_form extends moodleform { var $_category; function definition() { - global $CFG, $DB; + $mform = & $this->_form; + $this->_category = $this->_customdata; + $categorycontext = context_coursecat::instance($this->_category->id); - $mform =& $this->_form; - $category = $this->_customdata; - $categorycontext = context_coursecat::instance($category->id); - $this->_category = $category; + // Check permissions, to see if it OK to give the option to delete + // the contents, rather than move elsewhere. + $candeletecontent = $this->_category->can_delete_full(); - /// Check permissions, to see if it OK to give the option to delete - /// the contents, rather than move elsewhere. - /// Are there any subcategories of this one, can they be deleted? - $candeletecontent = true; - $tocheck = get_child_categories($category->id); - $containscategories = !empty($tocheck); - $categoryids = array($category->id); - while (!empty($tocheck)) { - $checkcat = array_pop($tocheck); - $childcategoryids[] = $checkcat->id; - $tocheck = $tocheck + get_child_categories($checkcat->id); - $chcontext = context_coursecat::instance($checkcat->id); - if ($candeletecontent && !has_capability('moodle/category:manage', $chcontext)) { - $candeletecontent = false; - } - } + // Get the list of categories we might be able to move to. + $displaylist = $this->_category->move_content_targets_list(); - /// Are there any courses in here, can they be deleted? - list($test, $params) = $DB->get_in_or_equal($categoryids); - $containedcourses = $DB->get_records_sql( - "SELECT id,1 FROM {course} c WHERE c.category $test", $params); - $containscourses = false; - if ($containedcourses) { - $containscourses = true; - foreach ($containedcourses as $courseid => $notused) { - if ($candeletecontent && !can_delete_course($courseid)) { - $candeletecontent = false; - break; - } - } - } - - /// Are there any questions in the question bank here? - $containsquestions = question_context_has_any_questions($categorycontext); - - /// Get the list of categories we might be able to move to. - $testcaps = array(); - if ($containscourses) { - $testcaps[] = 'moodle/course:create'; - } - if ($containscategories || $containsquestions) { - $testcaps[] = 'moodle/category:manage'; - } - if (!empty($testcaps)) { - $displaylist = coursecat::make_categories_list($testcaps, $category->id); - } - - /// Now build the options. + // Now build the options. $options = array(); if ($displaylist) { $options[0] = get_string('movecontentstoanothercategory'); @@ -75,60 +32,57 @@ class delete_category_form extends moodleform { if ($candeletecontent) { $options[1] = get_string('deleteallcannotundo'); } + if (empty($options)) { + print_error('youcannotdeletecategory', 'error', 'index.php', $this->_category->get_formatted_name()); + } - /// Now build the form. - $mform->addElement('header','general', get_string('categorycurrentcontents', '', format_string($category->name, true, array('context' => $categorycontext)))); + // Now build the form. + $mform->addElement('header','general', get_string('categorycurrentcontents', '', $this->_category->get_formatted_name())); - if ($containscourses || $containscategories || $containsquestions) { - if (empty($options)) { - print_error('youcannotdeletecategory', 'error', 'index.php', format_string($category->name, true, array('context' => $categorycontext))); - } - - /// Describe the contents of this category. - $contents = ''; - $mform->addElement('static', 'emptymessage', get_string('thiscategorycontains'), $contents); - - /// Give the options for what to do. - $mform->addElement('select', 'fulldelete', get_string('whattodo'), $options); - if (count($options) == 1) { - $optionkeys = array_keys($options); - $option = reset($optionkeys); - $mform->hardFreeze('fulldelete'); - $mform->setConstant('fulldelete', $option); - } - - if ($displaylist) { - $mform->addElement('select', 'newparent', get_string('movecategorycontentto'), $displaylist); - if (in_array($category->parent, $displaylist)) { - $mform->setDefault('newparent', $category->parent); - } - $mform->disabledIf('newparent', 'fulldelete', 'eq', '1'); - } + // Describe the contents of this category. + $contents = ''; + if ($this->_category->has_children()) { + $contents .= '
  • ' . get_string('subcategories') . '
  • '; + } + if ($this->_category->has_courses()) { + $contents .= '
  • ' . get_string('courses') . '
  • '; + } + if (question_context_has_any_questions($categorycontext)) { + $contents .= '
  • ' . get_string('questionsinthequestionbank') . '
  • '; + } + if (!empty($contents)) { + $mform->addElement('static', 'emptymessage', get_string('thiscategorycontains'), html_writer::tag('ul', $contents)); } else { - $mform->addElement('hidden', 'fulldelete', 1); - $mform->setType('fulldelete', PARAM_INT); $mform->addElement('static', 'emptymessage', '', get_string('deletecategoryempty')); } + // Give the options for what to do. + $mform->addElement('select', 'fulldelete', get_string('whattodo'), $options); + if (count($options) == 1) { + $optionkeys = array_keys($options); + $option = reset($optionkeys); + $mform->hardFreeze('fulldelete'); + $mform->setConstant('fulldelete', $option); + } + + if ($displaylist) { + $mform->addElement('select', 'newparent', get_string('movecategorycontentto'), $displaylist); + if (in_array($this->_category->parent, $displaylist)) { + $mform->setDefault('newparent', $this->_category->parent); + } + $mform->disabledIf('newparent', 'fulldelete', 'eq', '1'); + } + $mform->addElement('hidden', 'deletecat'); $mform->setType('deletecat', PARAM_ALPHANUM); $mform->addElement('hidden', 'sure'); $mform->setType('sure', PARAM_ALPHANUM); - $mform->setDefault('sure', md5(serialize($category))); + $mform->setDefault('sure', md5(serialize($this->_category))); //-------------------------------------------------------------------------------- $this->add_action_buttons(true, get_string('delete')); + $this->set_data(array('deletecat' => $this->_category->id)); } /// perform some extra moodle validation diff --git a/course/externallib.php b/course/externallib.php index 3063966d57f..d7a3a6e4232 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -1864,6 +1864,7 @@ class core_course_external extends external_api { 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)); @@ -1871,9 +1872,7 @@ class core_course_external extends external_api { $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'); - } + $deletecat = coursecat::get($category['id'], MUST_EXIST); $context = context_coursecat::instance($deletecat->id); require_capability('moodle/category:manage', $context); self::validate_context($context); @@ -1881,29 +1880,32 @@ class core_course_external extends external_api { if ($category['recursive']) { // If recursive was specified, then we recursively delete the category's contents. - category_delete_full($deletecat, false); + 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'])) { - if (!$DB->record_exists('course_categories', array('id' => $category['newparent']))) { - throw new moodle_exception('unknowcategory'); - } - $newparent = $category['newparent']; + $newparentcat = coursecat::get($category['newparent']); } else { - $newparent = $deletecat->parent; + $newparentcat = coursecat::get($deletecat->parent); } // This operation is not allowed. We must move contents to an existing category. - if ($newparent == 0) { + if (!$newparentcat->id) { 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); + 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()); + } } } diff --git a/course/lib.php b/course/lib.php index cede1373266..5c7f99baae6 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2636,112 +2636,6 @@ function course_allowed_module($course, $modname) { return has_capability($capability, $coursecontext); } -/** - * Recursively delete category including all subcategories and courses. - * @param stdClass $category - * @param boolean $showfeedback display some notices - * @return array return deleted courses - */ -function category_delete_full($category, $showfeedback=true) { - global $CFG, $DB; - require_once($CFG->libdir.'/gradelib.php'); - require_once($CFG->libdir.'/questionlib.php'); - require_once($CFG->dirroot.'/cohort/lib.php'); - - if ($children = $DB->get_records('course_categories', array('parent'=>$category->id), 'sortorder ASC')) { - foreach ($children as $childcat) { - category_delete_full($childcat, $showfeedback); - } - } - - $deletedcourses = array(); - if ($courses = $DB->get_records('course', array('category'=>$category->id), 'sortorder ASC')) { - foreach ($courses as $course) { - if (!delete_course($course, false)) { - throw new moodle_exception('cannotdeletecategorycourse','','',$course->shortname); - } - $deletedcourses[] = $course; - } - } - - // move or delete cohorts in this context - cohort_delete_category($category); - - // now delete anything that may depend on course category context - grade_course_category_delete($category->id, 0, $showfeedback); - if (!question_delete_course_category($category, 0, $showfeedback)) { - throw new moodle_exception('cannotdeletecategoryquestions','','',$category->name); - } - - // finally delete the category and it's context - $DB->delete_records('course_categories', array('id'=>$category->id)); - delete_context(CONTEXT_COURSECAT, $category->id); - add_to_log(SITEID, "category", "delete", "index.php", "$category->name (ID $category->id)"); - - events_trigger('course_category_deleted', $category); - - return $deletedcourses; -} - -/** - * Delete category, but move contents to another category. - * @param object $ccategory - * @param int $newparentid category id - * @return bool status - */ -function category_delete_move($category, $newparentid, $showfeedback=true) { - global $CFG, $DB, $OUTPUT; - require_once($CFG->libdir.'/gradelib.php'); - require_once($CFG->libdir.'/questionlib.php'); - require_once($CFG->dirroot.'/cohort/lib.php'); - - if (!$newparentcat = $DB->get_record('course_categories', array('id'=>$newparentid))) { - return false; - } - - if ($children = $DB->get_records('course_categories', array('parent'=>$category->id), 'sortorder ASC')) { - foreach ($children as $childcat) { - move_category($childcat, $newparentcat); - } - } - - if ($courses = $DB->get_records('course', array('category'=>$category->id), 'sortorder ASC', 'id')) { - if (!move_courses(array_keys($courses), $newparentid)) { - if ($showfeedback) { - echo $OUTPUT->notification("Error moving courses"); - } - return false; - } - if ($showfeedback) { - echo $OUTPUT->notification(get_string('coursesmovedout', '', format_string($category->name)), 'notifysuccess'); - } - } - - // move or delete cohorts in this context - cohort_delete_category($category); - - // now delete anything that may depend on course category context - grade_course_category_delete($category->id, $newparentid, $showfeedback); - if (!question_delete_course_category($category, $newparentcat, $showfeedback)) { - if ($showfeedback) { - echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $category), 'notifysuccess'); - } - return false; - } - - // finally delete the category and it's context - $DB->delete_records('course_categories', array('id'=>$category->id)); - delete_context(CONTEXT_COURSECAT, $category->id); - add_to_log(SITEID, "category", "delete", "index.php", "$category->name (ID $category->id)"); - - events_trigger('course_category_deleted', $category); - - if ($showfeedback) { - echo $OUTPUT->notification(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess'); - } - return true; -} - /** * Efficiently moves many courses around while maintaining * sortorder in order. @@ -2842,6 +2736,9 @@ function course_category_show($category) { /** * Efficiently moves a category - NOTE that this can have * a huge impact access-control-wise... + * + * @param stdClass|coursecat $category + * @param stdClass|coursecat $newparentcat */ function move_category($category, $newparentcat) { global $CFG, $DB; diff --git a/course/manage.php b/course/manage.php index a80fb223540..9721c4a2f04 100644 --- a/course/manage.php +++ b/course/manage.php @@ -24,6 +24,7 @@ require_once("../config.php"); require_once($CFG->dirroot.'/course/lib.php'); +require_once($CFG->libdir.'/coursecatlib.php'); // Category id. $id = optional_param('id', 0, PARAM_INT); @@ -94,7 +95,7 @@ if (!$id && !$DB->record_exists('course_categories', array('parent' => 0))) { // Process any category actions. if (!empty($deletecat) and confirm_sesskey()) { // Delete a category. - $cattodelete = $DB->get_record('course_categories', array('id' => $deletecat), '*', MUST_EXIST); + $cattodelete = coursecat::get($deletecat); $context = context_coursecat::instance($deletecat); require_capability('moodle/category:manage', $context); require_capability('moodle/category:manage', get_category_or_system_context($cattodelete->parent)); @@ -103,7 +104,6 @@ if (!empty($deletecat) and confirm_sesskey()) { require_once($CFG->dirroot.'/course/delete_category_form.php'); $mform = new delete_category_form(null, $cattodelete); - $mform->set_data(array('deletecat' => $deletecat)); if ($mform->is_cancelled()) { redirect(new moodle_url('/course/manage.php')); } @@ -114,25 +114,24 @@ if (!empty($deletecat) and confirm_sesskey()) { if ($data = $mform->get_data()) { // The form has been submit handle it. - if ($data->fulldelete) { - $deletedcourses = category_delete_full($cattodelete, true); + if ($data->fulldelete == 1 && $cattodelete->can_delete_full()) { + $cattodeletename = $cattodelete->get_formatted_name(); + $deletedcourses = $cattodelete->delete_full(true); foreach ($deletedcourses as $course) { echo $OUTPUT->notification(get_string('coursedeleted', '', $course->shortname), 'notifysuccess'); } - $cattodeletename = format_string($cattodelete->name, true, array('context' => $context)); echo $OUTPUT->notification(get_string('coursecategorydeleted', '', $cattodeletename), 'notifysuccess'); + echo $OUTPUT->continue_button(new moodle_url('/course/manage.php')); + } else if ($data->fulldelete == 0 && $cattodelete->can_move_content_to($data->newparent)) { + $cattodelete->delete_move($data->newparent, true); + echo $OUTPUT->continue_button(new moodle_url('/course/manage.php')); } else { - category_delete_move($cattodelete, $data->newparent, true); + // Some error in parameters (user is cheating?) + $mform->display(); } - if ($deletecat == $CFG->defaultrequestcategory) { - // If we deleted $CFG->defaultrequestcategory, make it point somewhere else. - set_config('defaultrequestcategory', $DB->get_field('course_categories', 'MIN(id)', array('parent' => 0))); - } - echo $OUTPUT->continue_button(new moodle_url('/course/manage.php')); } else { // Display the form. - require_once($CFG->libdir . '/questionlib.php'); $mform->display(); } // Finish output and exit. diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index 19d2e5d41b1..70d3188ae96 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -3499,3 +3499,47 @@ function make_categories_list(&$list, &$parents, $requiredcapability = '', } } } + +/** + * Delete category, but move contents to another category. + * + * This function is deprecated. Please use + * coursecat::get($category->id)->delete_move($newparentid, $showfeedback); + * + * @see coursecat::delete_move() + * @deprecated since 2.5 + * + * @param object $category + * @param int $newparentid category id + * @return bool status + */ +function category_delete_move($category, $newparentid, $showfeedback=true) { + global $CFG; + require_once($CFG->libdir.'/coursecatlib.php'); + + debugging('Function category_delete_move() is deprecated. Please use coursecat::delete_move() instead.'); + + return coursecat::get($category->id)->delete_move($newparentid, $showfeedback); +} + +/** + * Recursively delete category including all subcategories and courses. + * + * This function is deprecated. Please use + * coursecat::get($category->id)->delete_full($showfeedback); + * + * @see coursecat::delete_full() + * @deprecated since 2.5 + * + * @param stdClass $category + * @param boolean $showfeedback display some notices + * @return array return deleted courses + */ +function category_delete_full($category, $showfeedback=true) { + global $CFG, $DB; + require_once($CFG->libdir.'/coursecatlib.php'); + + debugging('Function category_delete_full() is deprecated. Please use coursecat::delete_full() instead.'); + + return coursecat::get($category->id)->delete_full($showfeedback); +} diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 084bc9f08f6..0d0c081e264 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -35,7 +35,8 @@ information provided here is intended especially for developers. param $formatoptions, that will determine if the field names are processed by format_string() with the passed options. * Functions responsible for managing and accessing course categories are moved to class coursecat - in lib/coursecatlib.php. The following global functions are deprecated: make_categories_list() + in lib/coursecatlib.php. The following global functions are deprecated: make_categories_list(), + category_delete_move(), category_delete_full() YUI changes: * M.util.help_icon has been deprecated. Code should be updated to use moodle-core-popuphelp