Example #1
0
/**
 * Remove a question from a quiz
 * @param object $quiz the quiz object.
 * @param int $questionid The id of the question to be deleted.
 */
function quiz_remove_question($quiz, $questionid)
{
    global $DB;
    $questionids = explode(',', $quiz->questions);
    $key = array_search($questionid, $questionids);
    if ($key === false) {
        return;
    }
    unset($questionids[$key]);
    $quiz->questions = implode(',', $questionids);
    $DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id));
    $DB->delete_records('quiz_question_instances', array('quiz' => $quiz->instance, 'question' => $questionid));
    $qtype = $DB->get_field('question', 'qtype', array('id' => $questionid));
    if ($qtype === 'random') {
        // This function automatically checks if the question is in use, and won't delete if it is.
        question_delete_question($questionid);
    }
}
Example #2
0
/**
 * Remove a question from a quiz
 * @param object $quiz the quiz object.
 * @param int $questionid The id of the question to be deleted.
 */
function quiz_remove_slot($quiz, $slotnumber)
{
    global $DB;
    $slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'slot' => $slotnumber));
    $maxslot = $DB->get_field_sql('SELECT MAX(slot) FROM {quiz_slots} WHERE quizid = ?', array($quiz->id));
    if (!$slot) {
        return;
    }
    $trans = $DB->start_delegated_transaction();
    $DB->delete_records('quiz_slots', array('id' => $slot->id));
    for ($i = $slot->slot + 1; $i <= $maxslot; $i++) {
        $DB->set_field('quiz_slots', 'slot', $i - 1, array('quizid' => $quiz->id, 'slot' => $i));
    }
    $qtype = $DB->get_field('question', 'qtype', array('id' => $slot->questionid));
    if ($qtype === 'random') {
        // This function automatically checks if the question is in use, and won't delete if it is.
        question_delete_question($slot->questionid);
    }
    $trans->allow_commit();
}
/**
 * All question categories and their questions are deleted for this activity.
 *
 * @param object $cm the course module object representing the activity
 * @param boolean $feedback to specify if the process must output a summary of its work
 * @return boolean
 */
function question_delete_activity($cm, $feedback = true)
{
    global $DB, $OUTPUT;
    //To store feedback to be showed at the end of the process
    $feedbackdata = array();
    //Cache some strings
    $strcatdeleted = get_string('unusedcategorydeleted', 'quiz');
    $modcontext = context_module::instance($cm->id);
    if ($categoriesmods = $DB->get_records('question_categories', array('contextid' => $modcontext->id), 'parent', 'id, parent, name, contextid')) {
        //Sort categories following their tree (parent-child) relationships
        //this will make the feedback more readable
        $categoriesmods = sort_categories_by_tree($categoriesmods);
        foreach ($categoriesmods as $category) {
            //Delete it completely (questions and category itself)
            //deleting questions
            if ($questions = $DB->get_records('question', array('category' => $category->id), '', 'id,qtype')) {
                foreach ($questions as $question) {
                    question_delete_question($question->id);
                }
                $DB->delete_records("question", array("category" => $category->id));
            }
            //delete the category
            $DB->delete_records('question_categories', array('id' => $category->id));
            //Fill feedback
            $feedbackdata[] = array($category->name, $strcatdeleted);
        }
        //Inform about changes performed if feedback is enabled
        if ($feedback) {
            $table = new html_table();
            $table->head = array(get_string('category', 'quiz'), get_string('action'));
            $table->data = $feedbackdata;
            echo html_writer::table($table);
        }
    }
    return true;
}
Example #4
0
/**
 * Deletes question and all associated data from the database
 *
 * It will not delete a question if it is used by an activity module
 * @param object $question  The question being deleted
 */
function question_delete_question($questionid)
{
    global $DB;
    $question = $DB->get_record_sql('
            SELECT q.*, qc.contextid
            FROM {question} q
            JOIN {question_categories} qc ON qc.id = q.category
            WHERE q.id = ?', array($questionid));
    if (!$question) {
        // In some situations, for example if this was a child of a
        // Cloze question that was previously deleted, the question may already
        // have gone. In this case, just do nothing.
        return;
    }
    // Do not delete a question if it is used by an activity module
    if (questions_in_use(array($questionid))) {
        return;
    }
    $dm = new question_engine_data_mapper();
    $dm->delete_previews($questionid);
    // delete questiontype-specific data
    question_bank::get_qtype($question->qtype, false)->delete_question($questionid, $question->contextid);
    // Delete all tag instances.
    $DB->delete_records('tag_instance', array('component' => 'core_question', 'itemid' => $question->id));
    // Now recursively delete all child questions
    if ($children = $DB->get_records('question', array('parent' => $questionid), '', 'id, qtype')) {
        foreach ($children as $child) {
            if ($child->id != $questionid) {
                question_delete_question($child->id);
            }
        }
    }
    // Finally delete the question record itself
    $DB->delete_records('question', array('id' => $questionid));
    question_bank::notify_question_edited($questionid);
}
Example #5
0
 public function save_question_options($question)
 {
     global $DB;
     $result = new stdClass();
     // This function needs to be able to handle the case where the existing set of wrapped
     // questions does not match the new set of wrapped questions so that some need to be
     // created, some modified and some deleted
     // Unfortunately the code currently simply overwrites existing ones in sequence. This
     // will make re-marking after a re-ordering of wrapped questions impossible and
     // will also create difficulties if questiontype specific tables reference the id.
     // First we get all the existing wrapped questions
     if (!($oldwrappedids = $DB->get_field('question_multianswer', 'sequence', array('question' => $question->id)))) {
         $oldwrappedquestions = array();
     } else {
         $oldwrappedquestions = $DB->get_records_list('question', 'id', explode(',', $oldwrappedids), 'id ASC');
     }
     $sequence = array();
     foreach ($question->options->questions as $wrapped) {
         if (!empty($wrapped)) {
             // if we still have some old wrapped question ids, reuse the next of them
             if (is_array($oldwrappedquestions) && ($oldwrappedquestion = array_shift($oldwrappedquestions))) {
                 $wrapped->id = $oldwrappedquestion->id;
                 if ($oldwrappedquestion->qtype != $wrapped->qtype) {
                     switch ($oldwrappedquestion->qtype) {
                         case 'multichoice':
                             $DB->delete_records('question_multichoice', array('question' => $oldwrappedquestion->id));
                             break;
                         case 'shortanswer':
                             $DB->delete_records('question_shortanswer', array('question' => $oldwrappedquestion->id));
                             break;
                         case 'numerical':
                             $DB->delete_records('question_numerical', array('question' => $oldwrappedquestion->id));
                             break;
                         default:
                             throw new moodle_exception('qtypenotrecognized', 'qtype_multianswer', '', $oldwrappedquestion->qtype);
                             $wrapped->id = 0;
                     }
                 }
             } else {
                 $wrapped->id = 0;
             }
         }
         $wrapped->name = $question->name;
         $wrapped->parent = $question->id;
         $previousid = $wrapped->id;
         // save_question strips this extra bit off the category again.
         $wrapped->category = $question->category . ',1';
         $wrapped = question_bank::get_qtype($wrapped->qtype)->save_question($wrapped, clone $wrapped);
         $sequence[] = $wrapped->id;
         if ($previousid != 0 && $previousid != $wrapped->id) {
             // for some reasons a new question has been created
             // so delete the old one
             question_delete_question($previousid);
         }
     }
     // Delete redundant wrapped questions
     if (is_array($oldwrappedquestions) && count($oldwrappedquestions)) {
         foreach ($oldwrappedquestions as $oldwrappedquestion) {
             question_delete_question($oldwrappedquestion->id);
         }
     }
     if (!empty($sequence)) {
         $multianswer = new stdClass();
         $multianswer->question = $question->id;
         $multianswer->sequence = implode(',', $sequence);
         if ($oldid = $DB->get_field('question_multianswer', 'id', array('question' => $question->id))) {
             $multianswer->id = $oldid;
             $DB->update_record('question_multianswer', $multianswer);
         } else {
             $DB->insert_record('question_multianswer', $multianswer);
         }
     }
     $this->save_hints($question);
 }
Example #6
0
File: lib.php Project: dg711/moodle
/**
 * Given an ID of an instance of this module,
 * this function will permanently delete the instance
 * and any data that depends on it.
 *
 * @param int $id the id of the quiz to delete.
 * @return bool success or failure.
 */
function quiz_delete_instance($id)
{
    global $DB;
    $quiz = $DB->get_record('quiz', array('id' => $id), '*', MUST_EXIST);
    quiz_delete_all_attempts($quiz);
    quiz_delete_all_overrides($quiz);
    // Look for random questions that may no longer be used when this quiz is gone.
    $sql = "SELECT q.id\n              FROM {quiz_slots} slot\n              JOIN {question} q ON q.id = slot.questionid\n             WHERE slot.quizid = ? AND q.qtype = ?";
    $questionids = $DB->get_fieldset_sql($sql, array($quiz->id, 'random'));
    // We need to do this before we try and delete randoms, otherwise they would still be 'in use'.
    $DB->delete_records('quiz_slots', array('quizid' => $quiz->id));
    $DB->delete_records('quiz_sections', array('quizid' => $quiz->id));
    foreach ($questionids as $questionid) {
        question_delete_question($questionid);
    }
    $DB->delete_records('quiz_feedback', array('quizid' => $quiz->id));
    quiz_access_manager::delete_settings($quiz);
    $events = $DB->get_records('event', array('modulename' => 'quiz', 'instance' => $quiz->id));
    foreach ($events as $event) {
        $event = calendar_event::load($event);
        $event->delete();
    }
    quiz_grade_item_delete($quiz);
    $DB->delete_records('quiz', array('id' => $quiz->id));
    return true;
}
Example #7
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);
        }
    }
 /**
  * Remove a slot from a offlinequiz
  * @param \stdClass $offlinequiz the offlinequiz object.
  * @param int $slotnumber The number of the slot to be deleted.
  */
 public function remove_slot($offlinequiz, $slotnumber)
 {
     global $DB;
     $this->check_can_be_edited();
     $slot = $DB->get_record('offlinequiz_group_questions', array('offlinequizid' => $offlinequiz->id, 'offlinegroupid' => $offlinequiz->groupid, 'slot' => $slotnumber));
     $maxslot = $DB->get_field_sql('SELECT MAX(slot) 
                                      FROM {offlinequiz_group_questions}
                                     WHERE offlinequizid = ?
                                       AND offlinegroupid = ?', array($offlinequiz->id, $offlinequiz->groupid));
     if (!$slot) {
         return;
     }
     $trans = $DB->start_delegated_transaction();
     $DB->delete_records('offlinequiz_group_questions', array('id' => $slot->id));
     for ($i = $slot->slot + 1; $i <= $maxslot; $i++) {
         $DB->set_field('offlinequiz_group_questions', 'slot', $i - 1, array('offlinequizid' => $offlinequiz->id, 'offlinegroupid' => $offlinequiz->groupid, 'slot' => $i));
     }
     $qtype = $DB->get_field('question', 'qtype', array('id' => $slot->questionid));
     if ($qtype === 'random') {
         // This function automatically checks if the question is in use, and won't delete if it is.
         question_delete_question($slot->questionid);
     }
     unset($this->questions[$slot->questionid]);
     $this->refresh_page_numbers_and_update_db($offlinequiz);
     $trans->allow_commit();
 }
function RWSDQCat($r_qci)
{
    global $DB;
    global $CFG;
    $r_chn = $DB->get_records("question_categories", array("parent" => $r_qci));
    if (count($r_chn) > 0) {
        foreach ($r_chn as $r_chd) {
            RWSDQCat($r_chd->id);
        }
    }
    $r_qsts = $DB->get_records("question", array("category" => $r_qci));
    if (count($r_qsts) > 0) {
        foreach ($r_qsts as $r_q) {
            if (respondusws_floatcompare($CFG->version, 2011070100, 2) >= 0) {
                question_delete_question($r_q->id);
            } else {
                delete_question($r_q->id);
            }
        }
        $DB->delete_records("question", array("category" => $r_qci));
    }
    $DB->delete_records("question_categories", array("id" => $r_qci));
}
Example #10
0
 /**
  * Remove a slot from a quiz
  * @param int $slotnumber The number of the slot to be deleted.
  */
 public function remove_slot($slotnumber)
 {
     global $DB;
     $this->check_can_be_edited();
     if ($this->is_only_slot_in_section($slotnumber)) {
         throw new \coding_exception('You cannot remove the last slot in a section.');
     }
     $slot = $DB->get_record('quiz_slots', array('quizid' => $this->get_quizid(), 'slot' => $slotnumber));
     if (!$slot) {
         return;
     }
     $maxslot = $DB->get_field_sql('SELECT MAX(slot) FROM {quiz_slots} WHERE quizid = ?', array($this->get_quizid()));
     $trans = $DB->start_delegated_transaction();
     $DB->delete_records('quiz_slots', array('id' => $slot->id));
     for ($i = $slot->slot + 1; $i <= $maxslot; $i++) {
         $DB->set_field('quiz_slots', 'slot', $i - 1, array('quizid' => $this->get_quizid(), 'slot' => $i));
     }
     $qtype = $DB->get_field('question', 'qtype', array('id' => $slot->questionid));
     if ($qtype === 'random') {
         // This function automatically checks if the question is in use, and won't delete if it is.
         question_delete_question($slot->questionid);
     }
     $DB->execute("\n                UPDATE {quiz_sections}\n                   SET firstslot = firstslot - 1\n                 WHERE quizid = ?\n                   AND firstslot > ?\n                ", array($this->get_quizid(), $slotnumber));
     unset($this->questions[$slot->questionid]);
     $this->refresh_page_numbers_and_update_db();
     $trans->allow_commit();
 }