Example #1
0
 /**
  * This function tests the question_delete_course_category function.
  *
  * @param bool $feedback Whether to return feedback
  * @dataProvider provider_feedback
  */
 public function test_question_delete_course_category($feedback)
 {
     global $DB;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     list($category, $course, $quiz, $qcat, $questions) = $this->setup_quiz_and_questions('category');
     // Test that the feedback works.
     if ($feedback) {
         $this->expectOutputRegex('|' . get_string('unusedcategorydeleted', 'question') . '|');
     }
     question_delete_course_category($category, 0, $feedback);
     // Verify category deleted.
     $criteria = array('id' => $qcat->id);
     $this->assertEquals(0, $DB->count_records('question_categories', $criteria));
     // Verify questions deleted or moved.
     $criteria = array('category' => $qcat->id);
     $this->assertEquals(0, $DB->count_records('question', $criteria));
 }
Example #2
0
/**
 * 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)) {
            echo $OUTPUT->notification("Error moving courses");
            return false;
        }
        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)) {
        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);
    events_trigger('course_category_deleted', $category);
    echo $OUTPUT->notification(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess');
    return true;
}
 /**
  * Deletes a category and moves all content (children, courses and questions) to the new parent
  *
  * Note that this function does not check capabilities, {@link coursecat::can_move_content_to()}
  * must be called prior
  *
  * @param int $newparentid
  * @param bool $showfeedback
  * @return bool
  */
 public function delete_move($newparentid, $showfeedback = false)
 {
     global $CFG, $DB, $OUTPUT;
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->libdir . '/questionlib.php';
     require_once $CFG->dirroot . '/cohort/lib.php';
     // Get all objects and lists because later the caches will be reset so.
     // We don't need to make extra queries.
     $newparentcat = self::get($newparentid, MUST_EXIST, true);
     $catname = $this->get_formatted_name();
     $children = $this->get_children();
     $params = array('category' => $this->id);
     $coursesids = $DB->get_fieldset_select('course', 'id', 'category = :category ORDER BY sortorder ASC', $params);
     $context = $this->get_context();
     if ($children) {
         foreach ($children as $childcat) {
             $childcat->change_parent_raw($newparentcat);
             // Log action.
             $event = \core\event\course_category_updated::create(array('objectid' => $childcat->id, 'context' => $childcat->get_context()));
             $event->set_legacy_logdata(array(SITEID, 'category', 'move', 'editcategory.php?id=' . $childcat->id, $childcat->id));
             $event->trigger();
         }
         fix_course_sortorder();
     }
     if ($coursesids) {
         if (!move_courses($coursesids, $newparentid)) {
             if ($showfeedback) {
                 echo $OUTPUT->notification("Error moving courses");
             }
             return false;
         }
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('coursesmovedout', '', $catname), 'notifysuccess');
         }
     }
     // Move or delete cohorts in this context.
     cohort_delete_category($this);
     // Now delete anything that may depend on course category context.
     grade_course_category_delete($this->id, $newparentid, $showfeedback);
     if (!question_delete_course_category($this, $newparentcat, $showfeedback)) {
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $catname), 'notifysuccess');
         }
         return false;
     }
     // Finally delete the category and it's context.
     $DB->delete_records('course_categories', array('id' => $this->id));
     $context->delete();
     // Trigger a course category deleted event.
     /* @var \core\event\course_category_deleted $event */
     $event = \core\event\course_category_deleted::create(array('objectid' => $this->id, 'context' => $context, 'other' => array('name' => $this->name)));
     $event->set_coursecat($this);
     $event->trigger();
     cache_helper::purge_by_event('changesincoursecat');
     if ($showfeedback) {
         echo $OUTPUT->notification(get_string('coursecategorydeleted', '', $catname), 'notifysuccess');
     }
     // If we deleted $CFG->defaultrequestcategory, make it point somewhere else.
     if ($this->id == $CFG->defaultrequestcategory) {
         set_config('defaultrequestcategory', $DB->get_field('course_categories', 'MIN(id)', array('parent' => 0)));
     }
     return true;
 }
Example #4
0
 /**
  * Deletes a category and moves all content (children, courses and questions) to the new parent
  *
  * Note that this function does not check capabilities, {@link coursecat::can_move_content_to()}
  * must be called prior
  *
  * @param int $newparentid
  * @param bool $showfeedback
  * @return bool
  */
 public function delete_move($newparentid, $showfeedback = false)
 {
     global $CFG, $DB, $OUTPUT;
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->libdir . '/questionlib.php';
     require_once $CFG->dirroot . '/cohort/lib.php';
     // get all objects and lists because later the caches will be reset so
     // we don't need to make extra queries
     $newparentcat = self::get($newparentid, MUST_EXIST, true);
     $catname = $this->get_formatted_name();
     $children = $this->get_children();
     $coursesids = $DB->get_fieldset_select('course', 'id', 'category = :category ORDER BY sortorder ASC', array('category' => $this->id));
     $context = context_coursecat::instance($this->id);
     if ($children) {
         foreach ($children as $childcat) {
             $childcat->change_parent_raw($newparentcat);
             // Log action.
             add_to_log(SITEID, "category", "move", "editcategory.php?id={$childcat->id}", $childcat->id);
         }
         fix_course_sortorder();
     }
     if ($coursesids) {
         if (!move_courses($coursesids, $newparentid)) {
             if ($showfeedback) {
                 echo $OUTPUT->notification("Error moving courses");
             }
             return false;
         }
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('coursesmovedout', '', $catname), 'notifysuccess');
         }
     }
     // move or delete cohorts in this context
     cohort_delete_category($this);
     // now delete anything that may depend on course category context
     grade_course_category_delete($this->id, $newparentid, $showfeedback);
     if (!question_delete_course_category($this, $newparentcat, $showfeedback)) {
         if ($showfeedback) {
             echo $OUTPUT->notification(get_string('errordeletingquestionsfromcategory', 'question', $catname), 'notifysuccess');
         }
         return false;
     }
     // finally delete the category and it's context
     $DB->delete_records('course_categories', array('id' => $this->id));
     $context->delete();
     add_to_log(SITEID, "category", "delete", "index.php", "{$this->name} (ID {$this->id})");
     events_trigger('course_category_deleted', $this);
     cache_helper::purge_by_event('changesincoursecat');
     if ($showfeedback) {
         echo $OUTPUT->notification(get_string('coursecategorydeleted', '', $catname), 'notifysuccess');
     }
     // If we deleted $CFG->defaultrequestcategory, make it point somewhere else.
     if ($this->id == $CFG->defaultrequestcategory) {
         set_config('defaultrequestcategory', $DB->get_field('course_categories', 'MIN(id)', array('parent' => 0)));
     }
     return true;
 }
Example #5
0
/**
 * 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;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->libdir . '/questionlib.php';
    if (!($newparentcat = get_record('course_categories', 'id', $newparentid))) {
        return false;
    }
    if ($children = get_records('course_categories', 'parent', $category->id, 'sortorder ASC')) {
        foreach ($children as $childcat) {
            if (!move_category($childcat, $newparentcat)) {
                notify("Error moving category {$childcat->name}");
                return false;
            }
        }
    }
    if ($courses = get_records('course', 'category', $category->id, 'sortorder ASC', 'id')) {
        if (!move_courses(array_keys($courses), $newparentid)) {
            notify("Error moving courses");
            return false;
        }
        notify(get_string('coursesmovedout', '', format_string($category->name)), 'notifysuccess');
    }
    // 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)) {
        notify(get_string('errordeletingquestionsfromcategory', 'question', $category), 'notifysuccess');
        return false;
    }
    // finally delete the category and it's context
    delete_records('course_categories', 'id', $category->id);
    delete_context(CONTEXT_COURSECAT, $category->id);
    events_trigger('course_category_deleted', $category);
    notify(get_string('coursecategorydeleted', '', format_string($category->name)), 'notifysuccess');
    return true;
}
Example #6
0
 /**
  * This function tests that the functions responsible for moving questions to
  * different contexts also updates the tag instances associated with the questions.
  */
 public function test_altering_tag_instance_context()
 {
     global $CFG, $DB;
     // Set to admin user.
     $this->setAdminUser();
     // Create two course categories - we are going to delete one of these later and will expect
     // all the questions belonging to the course in the deleted category to be moved.
     $coursecat1 = $this->getDataGenerator()->create_category();
     $coursecat2 = $this->getDataGenerator()->create_category();
     // Create a couple of categories and questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $questioncat1 = $questiongenerator->create_question_category(array('contextid' => context_coursecat::instance($coursecat1->id)->id));
     $questioncat2 = $questiongenerator->create_question_category(array('contextid' => context_coursecat::instance($coursecat2->id)->id));
     $question1 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat1->id));
     $question2 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat1->id));
     $question3 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat2->id));
     $question4 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat2->id));
     // Now lets tag these questions.
     tag_set('question', $question1->id, array('tag 1', 'tag 2'), 'core_question', $questioncat1->contextid);
     tag_set('question', $question2->id, array('tag 3', 'tag 4'), 'core_question', $questioncat1->contextid);
     tag_set('question', $question3->id, array('tag 5', 'tag 6'), 'core_question', $questioncat2->contextid);
     tag_set('question', $question4->id, array('tag 7', 'tag 8'), 'core_question', $questioncat2->contextid);
     // Test moving the questions to another category.
     question_move_questions_to_category(array($question1->id, $question2->id), $questioncat2->id);
     // Test that all tag_instances belong to one context.
     $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat2->contextid)));
     // Test moving them back.
     question_move_questions_to_category(array($question1->id, $question2->id), $questioncat1->id);
     // Test that all tag_instances are now reset to how they were initially.
     $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat1->contextid)));
     $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat2->contextid)));
     // Now test moving a whole question category to another context.
     question_move_category_to_context($questioncat1->id, $questioncat1->contextid, $questioncat2->contextid);
     // Test that all tag_instances belong to one context.
     $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat2->contextid)));
     // Now test moving them back.
     question_move_category_to_context($questioncat1->id, $questioncat2->contextid, context_coursecat::instance($coursecat1->id)->id);
     // Test that all tag_instances are now reset to how they were initially.
     $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat1->contextid)));
     $this->assertEquals(4, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat2->contextid)));
     // Now we want to test deleting the course category and moving the questions to another category.
     question_delete_course_category($coursecat1, $coursecat2, false);
     // Test that all tag_instances belong to one context.
     $this->assertEquals(8, $DB->count_records('tag_instance', array('component' => 'core_question', 'contextid' => $questioncat2->contextid)));
     // Create a course.
     $course = $this->getDataGenerator()->create_course();
     // Create some question categories and questions in this course.
     $questioncat = $questiongenerator->create_question_category(array('contextid' => context_course::instance($course->id)->id));
     $question1 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat->id));
     $question2 = $questiongenerator->create_question('shortanswer', null, array('category' => $questioncat->id));
     // Add some tags to these questions.
     tag_set('question', $question1->id, array('tag 1', 'tag 2'), 'core_question', $questioncat->contextid);
     tag_set('question', $question2->id, array('tag 1', 'tag 2'), 'core_question', $questioncat->contextid);
     // Create a course that we are going to restore the other course to.
     $course2 = $this->getDataGenerator()->create_course();
     // Create backup file and save it to the backup location.
     $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL, 2);
     $bc->execute_plan();
     $results = $bc->get_results();
     $file = $results['backup_destination'];
     $fp = get_file_packer();
     $filepath = $CFG->dataroot . '/temp/backup/test-restore-course';
     $file->extract_to_pathname($fp, $filepath);
     $bc->destroy();
     unset($bc);
     // Now restore the course.
     $rc = new restore_controller('test-restore-course', $course2->id, backup::INTERACTIVE_NO, backup::MODE_GENERAL, 2, backup::TARGET_NEW_COURSE);
     $rc->execute_precheck();
     $rc->execute_plan();
     // Get the created question category.
     $restoredcategory = $DB->get_record('question_categories', array('contextid' => context_course::instance($course2->id)->id), '*', MUST_EXIST);
     // Check that there are two questions in the restored to course's context.
     $this->assertEquals(2, $DB->count_records('question', array('category' => $restoredcategory->id)));
 }