Ejemplo n.º 1
0
     } 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';
         tag_set('question', $question->id, $fromform->tags);
     }
 }
 // Purge this question from the cache.
 question_bank::notify_question_edited($question->id);
 if ($qtypeobj->finished_edit_wizard($fromform) || $movecontext) {
     if ($inpopup) {
         echo $OUTPUT->notification(get_string('changessaved'), '');
         close_window(3);
     } else {
         $returnurl->param('lastchanged', $question->id);
         if ($appendqnumstring) {
             $returnurl->param($appendqnumstring, $question->id);
             $returnurl->param('sesskey', sesskey());
             $returnurl->param('cmid', $cmid);
         }
         redirect($returnurl);
     }
 } else {
     $nexturlparams = array('returnurl' => $originalreturnurl, 'appendqnumstring' => $appendqnumstring, 'scrollpos' => $scrollpos);
Ejemplo n.º 2
0
/**
 * This function helps move a question cateogry to a new context by moving all
 * the files belonging to all the questions to the new context.
 * Also moves subcategories.
 * @param integer $categoryid the id of the category being moved.
 * @param integer $oldcontextid the old context id.
 * @param integer $newcontextid the new context id.
 */
function question_move_category_to_context($categoryid, $oldcontextid, $newcontextid)
{
    global $DB;
    $questionids = $DB->get_records_menu('question', array('category' => $categoryid), '', 'id,qtype');
    foreach ($questionids as $questionid => $qtype) {
        question_bank::get_qtype($qtype)->move_files($questionid, $oldcontextid, $newcontextid);
        // Purge this question from the cache.
        question_bank::notify_question_edited($questionid);
    }
    $subcatids = $DB->get_records_menu('question_categories', array('parent' => $categoryid), '', 'id,1');
    foreach ($subcatids as $subcatid => $notused) {
        $DB->set_field('question_categories', 'contextid', $newcontextid, array('id' => $subcatid));
        question_move_category_to_context($subcatid, $oldcontextid, $newcontextid);
    }
}
Ejemplo n.º 3
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.º 4
0
/**
 * This function helps move a question cateogry to a new context by moving all
 * the files belonging to all the questions to the new context.
 * Also moves subcategories.
 * @param integer $categoryid the id of the category being moved.
 * @param integer $oldcontextid the old context id.
 * @param integer $newcontextid the new context id.
 */
function question_move_category_to_context($categoryid, $oldcontextid, $newcontextid)
{
    global $DB;
    $questionids = $DB->get_records_menu('question', array('category' => $categoryid), '', 'id,qtype');
    foreach ($questionids as $questionid => $qtype) {
        question_bank::get_qtype($qtype)->move_files($questionid, $oldcontextid, $newcontextid);
        // Purge this question from the cache.
        question_bank::notify_question_edited($questionid);
    }
    if ($questionids) {
        // Update the contextid for any tag instances that may exist for these questions.
        list($questionids, $params) = $DB->get_in_or_equal(array_keys($questionids));
        $DB->set_field_select('tag_instance', 'contextid', $newcontextid, "component = 'core_question' AND itemid {$questionids}", $params);
    }
    $subcatids = $DB->get_records_menu('question_categories', array('parent' => $categoryid), '', 'id,1');
    foreach ($subcatids as $subcatid => $notused) {
        $DB->set_field('question_categories', 'contextid', $newcontextid, array('id' => $subcatid));
        question_move_category_to_context($subcatid, $oldcontextid, $newcontextid);
    }
}
Ejemplo n.º 5
0
 public function save_question_options($question)
 {
     global $DB, $USER;
     assert(isset($question->coderunnertype));
     $fields = $this->extra_question_fields();
     array_shift($fields);
     // Discard table name
     $customised = isset($question->customise) && $question->customise;
     $isprototype = $question->prototypetype != 0;
     if ($customised && $question->prototypetype == 2 && $question->coderunnertype != $question->typename) {
         // Saving a new user-defined prototype.
         // Copy new type name into coderunnertype
         $question->coderunnertype = $question->typename;
     }
     // If we're saving a new prototype, make sure its coderunnertype is
     // unique by appending a suitable suffix. [Shouldn't happen via
     // question edit form, but could be a spurious import or a question
     // duplication mouse click.]
     if ($question->isnew && $isprototype) {
         $suffix = '';
         $type = $question->coderunnertype;
         while (true) {
             try {
                 $row = $this->get_prototype($type . $suffix, $question->context);
                 $suffix = $suffix == '' ? '-1' : $suffix - 1;
             } catch (coderunner_exception $e) {
                 break;
             }
         }
         $question->coderunnertype = $type . $suffix;
     }
     // Set all inherited fields to null if the corresponding form
     // field is blank or if it's being saved with customise explicitly
     // turned off and it's not a prototype.
     $questioninherits = isset($question->customise) && !$question->customise && !$isprototype;
     foreach ($fields as $field) {
         $isinherited = !in_array($field, $this->noninherited_fields());
         $isblankstring = !isset($question->{$field}) || is_string($question->{$field}) && trim($question->{$field}) === '';
         if ($isinherited && ($isblankstring || $questioninherits)) {
             $question->{$field} = null;
         }
     }
     if (trim($question->sandbox) === 'DEFAULT') {
         $question->sandbox = null;
     }
     parent::save_question_options($question);
     $testcasetable = "question_coderunner_tests";
     if (!isset($question->testcases)) {
         $this->copy_testcases_from_form($question);
     }
     if (!($oldtestcases = $DB->get_records($testcasetable, array('questionid' => $question->id), 'id ASC'))) {
         $oldtestcases = array();
     }
     foreach ($question->testcases as $tc) {
         if ($oldtestcase = array_shift($oldtestcases)) {
             // Existing testcase, so reuse it
             $tc->id = $oldtestcase->id;
             $DB->update_record($testcasetable, $tc);
         } else {
             // A new testcase
             $tc->questionid = $question->id;
             $id = $DB->insert_record($testcasetable, $tc);
         }
     }
     // delete old testcase records
     foreach ($oldtestcases as $otc) {
         $DB->delete_records($testcasetable, array('id' => $otc->id));
     }
     // If this is a prototype, clear the caching of any child questions
     if ($question->prototypetype != 0) {
         $typename = $question->coderunnertype;
         $children = $DB->get_records('question_coderunner_options', array('prototypetype' => 0, 'coderunnertype' => $typename));
         foreach ($children as $child) {
             question_bank::notify_question_edited($child->questionid);
         }
     }
     // Lastly, save any datafiles
     if ($USER->id && isset($question->datafiles)) {
         //  The id check is a hack to deal with phpunit initialisation, when no user exists
         file_save_draft_area_files($question->datafiles, $question->context->id, 'qtype_coderunner', 'datafile', (int) $question->id, $this->fileoptions);
     }
     return true;
 }