Ejemplo n.º 1
0
         // $fromform->category is the right category to save in.
     }
 }
 /// If we are moving a question, check we have permission to move it from
 /// whence it came. (Where we are moving to is validated by the form.)
 list($newcatid, $newcontextid) = explode(',', $fromform->category);
 if (!empty($question->id) && $newcatid != $question->category) {
     question_require_capability_on($question, 'move');
 }
 // Ensure we redirect back to the category the question is being saved into.
 $returnurl->param('category', $fromform->category);
 if ($movecontext) {
     // We are just moving the question to a different context.
     list($tocatid, $tocontextid) = explode(',', $fromform->categorymoveto);
     require_capability('moodle/question:add', context::instance_by_id($tocontextid));
     question_move_questions_to_category(array($question->id), $tocatid);
 } else {
     // We are acutally saving the question.
     if (!empty($question->id)) {
         question_require_capability_on($question, 'edit');
     } else {
         require_capability('moodle/question:add', context::instance_by_id($newcontextid));
         if (!empty($fromform->makecopy) && !$question->formoptions->cansaveasnew) {
             print_error('nopermissions', '', '', 'edit');
         }
     }
     $question = $qtypeobj->save_question($question, $fromform);
     if (!empty($CFG->usetags) && isset($fromform->tags)) {
         // A wizardpage from multipe pages questiontype like calculated may not
         // allow editing the question tags, hence the isset($fromform->tags) test.
         require_once $CFG->dirroot . '/tag/lib.php';
Ejemplo n.º 2
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.
     $context1 = context_coursecat::instance($coursecat1->id);
     $context2 = context_coursecat::instance($coursecat2->id);
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $questioncat1 = $questiongenerator->create_question_category(array('contextid' => $context1->id));
     $questioncat2 = $questiongenerator->create_question_category(array('contextid' => $context2->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.
     core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $context1, array('tag 1', 'tag 2'));
     core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $context1, array('tag 3', 'tag 4'));
     core_tag_tag::set_item_tags('core_question', 'question', $question3->id, $context2, array('tag 5', 'tag 6'));
     core_tag_tag::set_item_tags('core_question', 'question', $question4->id, $context2, array('tag 7', 'tag 8'));
     // 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.
     $coursecontext = context_course::instance($course->id);
     $questioncat = $questiongenerator->create_question_category(array('contextid' => $coursecontext->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.
     core_tag_tag::set_item_tags('core_question', 'question', $question1->id, $coursecontext, array('tag 1', 'tag 2'));
     core_tag_tag::set_item_tags('core_question', 'question', $question2->id, $coursecontext, array('tag 1', 'tag 2'));
     // 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('application/vnd.moodle.backup');
     $filepath = $CFG->dataroot . '/temp/backup/test-restore-course';
     $file->extract_to_pathname($fp, $filepath);
     $bc->destroy();
     // 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)));
     $rc->destroy();
 }
Ejemplo n.º 3
0
/**
 * Enter description here...
 *
 * @param string $questionids list of questionids
 * @param object $newcontext the context to create the saved category in.
 * @param string $oldplace a textual description of the think being deleted, e.g. from get_context_name
 * @param object $newcategory
 * @return mixed false on
 */
function question_save_from_deletion($questionids, $newcontextid, $oldplace, $newcategory = null)
{
    // Make a category in the parent context to move the questions to.
    if (is_null($newcategory)) {
        $newcategory = new object();
        $newcategory->parent = 0;
        $newcategory->contextid = $newcontextid;
        $newcategory->name = addslashes(get_string('questionsrescuedfrom', 'question', $oldplace));
        $newcategory->info = addslashes(get_string('questionsrescuedfrominfo', 'question', $oldplace));
        $newcategory->sortorder = 999;
        $newcategory->stamp = make_unique_id_code();
        if (!($newcategory->id = insert_record('question_categories', $newcategory))) {
            return false;
        }
    }
    // Move any remaining questions to the 'saved' category.
    if (!question_move_questions_to_category($questionids, $newcategory->id)) {
        return false;
    }
    return $newcategory;
}
Ejemplo n.º 4
0
function question_showbank_actions($pageurl, $cm)
{
    global $CFG, $COURSE;
    /// Now, check for commands on this page and modify variables as necessary
    if (optional_param('move', false, PARAM_BOOL) and confirm_sesskey()) {
        /// Move selected questions to new category
        $category = required_param('category', PARAM_SEQUENCE);
        list($tocategoryid, $contextid) = explode(',', $category);
        if (!($tocategory = get_record('question_categories', 'id', $tocategoryid, 'contextid', $contextid))) {
            error('Could not find category record');
        }
        $tocontext = get_context_instance_by_id($contextid);
        require_capability('moodle/question:add', $tocontext);
        $rawdata = (array) data_submitted();
        $questionids = array();
        foreach ($rawdata as $key => $value) {
            // Parse input for question ids
            if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
                $key = $matches[1];
                $questionids[] = $key;
            }
        }
        if ($questionids) {
            $questionidlist = join($questionids, ',');
            $sql = "SELECT q.*, c.contextid FROM {$CFG->prefix}question q, {$CFG->prefix}question_categories c WHERE q.id IN ({$questionidlist}) AND c.id = q.category";
            if (!($questions = get_records_sql($sql))) {
                print_error('questiondoesnotexist', 'question', $pageurl->out());
            }
            $checkforfiles = false;
            foreach ($questions as $question) {
                //check capabilities
                question_require_capability_on($question, 'move');
                $fromcontext = get_context_instance_by_id($question->contextid);
                if (get_filesdir_from_context($fromcontext) != get_filesdir_from_context($tocontext)) {
                    $checkforfiles = true;
                }
            }
            $returnurl = $pageurl->out(false, array('category' => "{$tocategoryid},{$contextid}"));
            if (!$checkforfiles) {
                if (!question_move_questions_to_category(implode(',', $questionids), $tocategory->id)) {
                    print_error('errormovingquestions', 'question', $returnurl, $questionids);
                }
                redirect($returnurl);
            } else {
                $movecontexturl = new moodle_url($CFG->wwwroot . '/question/contextmoveq.php', array('returnurl' => $returnurl, 'ids' => $questionidlist, 'tocatid' => $tocategoryid));
                if ($cm) {
                    $movecontexturl->param('cmid', $cm->id);
                } else {
                    $movecontexturl->param('courseid', $COURSE->id);
                }
                redirect($movecontexturl->out());
            }
        }
    }
    if (optional_param('deleteselected', false, PARAM_BOOL)) {
        // delete selected questions from the category
        if ($confirm = optional_param('confirm', '', PARAM_ALPHANUM) and confirm_sesskey()) {
            // teacher has already confirmed the action
            $deleteselected = required_param('deleteselected');
            if ($confirm == md5($deleteselected)) {
                if ($questionlist = explode(',', $deleteselected)) {
                    // for each question either hide it if it is in use or delete it
                    foreach ($questionlist as $questionid) {
                        question_require_capability_on($questionid, 'edit');
                        if (record_exists('quiz_question_instances', 'question', $questionid)) {
                            if (!set_field('question', 'hidden', 1, 'id', $questionid)) {
                                question_require_capability_on($questionid, 'edit');
                                error('Was not able to hide question');
                            }
                        } else {
                            delete_question($questionid);
                        }
                    }
                }
                redirect($pageurl->out());
            } else {
                error("Confirmation string was incorrect");
            }
        }
    }
    // Unhide a question
    if ($unhide = optional_param('unhide', '', PARAM_INT) and confirm_sesskey()) {
        question_require_capability_on($unhide, 'edit');
        if (!set_field('question', 'hidden', 0, 'id', $unhide)) {
            error("Failed to unhide the question.");
        }
        redirect($pageurl->out());
    }
}
Ejemplo n.º 5
0
                    $url = $flipurls[$key];
                    $questionswithlinks = array_unique($urls[$url]);
                    foreach ($questionswithlinks as $questionid) {
                        $QTYPES[$questions[$questionid]->qtype]->replace_file_links($questions[$questionid], $fromcoursefilesid, $tocoursefilesid, $url, $destination);
                    }
                    break;
                case QUESTION_FILEDONOTHING:
                    break;
                default:
                    error('Invalid action selected!', $returnurl);
                    break;
            }
        }
    }
    /// Now move questions.
    if (!question_move_questions_to_category($ids, $tocat->id)) {
        print_error('errormovingquestions', 'question', $returnurl, $ids);
    }
    redirect($returnurl);
}
$streditingcategories = get_string('editcategories', 'quiz');
$crumbs = array();
if ($cmid) {
    // Page header
    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
    $strupdatemodule = has_capability('moodle/course:manageactivities', $context) ? update_module_button($cm->id, $COURSE->id, get_string('modulename', $cm->modname)) : "";
    $crumbs[] = array('name' => get_string('modulenameplural', $cm->modname), 'link' => "{$CFG->wwwroot}/mod/{$cm->modname}/index.php?id={$COURSE->id}", 'type' => 'activity');
    $crumbs[] = array('name' => format_string($module->name), 'link' => "{$CFG->wwwroot}/mod/{$cm->modname}/view.php?id={$cm->id}", 'type' => 'title');
} else {
    // Print basic page layout.
    $strupdatemodule = '';
Ejemplo n.º 6
0
    public function process_actions() {
        global $CFG, $DB;
        /// Now, check for commands on this page and modify variables as necessary
        if (optional_param('move', false, PARAM_BOOL) and confirm_sesskey()) {
            // Move selected questions to new category
            $category = required_param('category', PARAM_SEQUENCE);
            list($tocategoryid, $contextid) = explode(',', $category);
            if (! $tocategory = $DB->get_record('question_categories', array('id' => $tocategoryid, 'contextid' => $contextid))) {
                print_error('cannotfindcate', 'question');
            }
            $tocontext = context::instance_by_id($contextid);
            require_capability('moodle/question:add', $tocontext);
            $rawdata = (array) data_submitted();
            $questionids = array();
            foreach ($rawdata as $key => $value) {    // Parse input for question ids
                if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
                    $key = $matches[1];
                    $questionids[] = $key;
                }
            }
            if ($questionids) {
                list($usql, $params) = $DB->get_in_or_equal($questionids);
                $sql = "";
                $questions = $DB->get_records_sql("
                        SELECT q.*, c.contextid
                        FROM {question} q
                        JOIN {question_categories} c ON c.id = q.category
                        WHERE q.id $usql", $params);
                foreach ($questions as $question){
                    question_require_capability_on($question, 'move');
                }
                question_move_questions_to_category($questionids, $tocategory->id);
                redirect($this->baseurl->out(false,
                        array('category' => "$tocategoryid,$contextid")));
            }
        }

        if (optional_param('deleteselected', false, PARAM_BOOL)) { // delete selected questions from the category
            if (($confirm = optional_param('confirm', '', PARAM_ALPHANUM)) and confirm_sesskey()) { // teacher has already confirmed the action
                $deleteselected = required_param('deleteselected', PARAM_RAW);
                if ($confirm == md5($deleteselected)) {
                    if ($questionlist = explode(',', $deleteselected)) {
                        // for each question either hide it if it is in use or delete it
                        foreach ($questionlist as $questionid) {
                            $questionid = (int)$questionid;
                            question_require_capability_on($questionid, 'edit');
                            if (questions_in_use(array($questionid))) {
                                $DB->set_field('question', 'hidden', 1, array('id' => $questionid));
                            } else {
                                question_delete_question($questionid);
                            }
                        }
                    }
                    redirect($this->baseurl);
                } else {
                    print_error('invalidconfirm', 'question');
                }
            }
        }

        // Unhide a question
        if(($unhide = optional_param('unhide', '', PARAM_INT)) and confirm_sesskey()) {
            question_require_capability_on($unhide, 'edit');
            $DB->set_field('question', 'hidden', 0, array('id' => $unhide));

            // Purge these questions from the cache.
            question_bank::notify_question_edited($unhide);

            redirect($this->baseurl);
        }
    }
Ejemplo n.º 7
0
 public function move_questions($oldcat, $newcat){
     global $DB;
     $questionids = $DB->get_records_select_menu('question',
             'category = ? AND (parent = 0 OR parent = id)', array($oldcat), '', 'id,1');
     question_move_questions_to_category(array_keys($questionids), $newcat);
 }
Ejemplo n.º 8
0
 function move_questions($oldcat, $newcat)
 {
     $questionids = get_records_select_menu('question', "category = {$oldcat} AND (parent = 0 OR parent = id)", '', 'id,1');
     if (!question_move_questions_to_category(implode(',', array_keys($questionids)), $newcat)) {
         print_error('errormovingquestions', 'question', $returnurl, $ids);
     }
 }
Ejemplo n.º 9
0
 public function move_questions($oldcat, $newcat)
 {
     global $DB;
     $questionids = $DB->get_records_select_menu('question', "category = ? AND (parent = 0 OR parent = id)", array($oldcat), '', 'id,1');
     $ids = implode(',', array_keys($questionids));
     if (!question_move_questions_to_category($ids, $newcat)) {
         print_error('errormovingquestions', 'question', $this->pageurl->out(), $ids);
     }
 }