// $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';
/** * 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(); }
/** * 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; }
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()); } }
$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 = '';
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); } }
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); }
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); } }
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); } }