function delete_question($questionid) {
global $QTYPES, $DB;
- if (!$question = $DB->get_record('question', array('id'=>$questionid))) {
+ $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.
// delete questiontype-specific data
question_require_capability_on($question, 'edit');
- if ($question) {
- if (isset($QTYPES[$question->qtype])) {
- $QTYPES[$question->qtype]->delete_question($questionid);
- }
- } else {
- echo "Question with id $questionid does not exist.<br />";
+ if (isset($QTYPES[$question->qtype])) {
+ $QTYPES[$question->qtype]->delete_question($questionid, $question->contextid);
}
if ($states = $DB->get_records('question_states', array('question'=>$questionid))) {
}
}
- // delete entries from all other question tables
+ // Delete entries from all other question tables
// It is important that this is done only after calling the questiontype functions
- $DB->delete_records("question_answers", array("question"=>$questionid));
- $DB->delete_records("question_states", array("question"=>$questionid));
- $DB->delete_records("question_sessions", array("questionid"=>$questionid));
+ $DB->delete_records('question_answers', array('question' => $questionid));
+ $DB->delete_records('question_states', array('question' => $questionid));
+ $DB->delete_records('question_sessions', array('questionid' => $questionid));
// Now recursively delete all child questions
if ($children = $DB->get_records('question', array('parent' => $questionid), '', 'id,qtype')) {
// Finally delete the question record itself
$DB->delete_records('question', array('id'=>$questionid));
-
- return;
}
/**
static $questions = array();
static $categories = array();
static $cachedcat = array();
- if ($cachecat != -1 && (array_search($cachecat, $cachedcat)===FALSE)){
- $questions += $DB->get_records('question', array('category'=>$cachecat));
+ if ($cachecat != -1 && array_search($cachecat, $cachedcat) === false) {
+ $questions += $DB->get_records('question', array('category' => $cachecat));
$cachedcat[] = $cachecat;
}
if (!is_object($question)){
if (!isset($questions[$question])){
- if (!$questions[$question] = $DB->get_record('question', array('id'=>$question), 'id,category,createdby')) {
+ if (!$questions[$question] = $DB->get_record('question', array('id' => $question), 'id,category,createdby')) {
print_error('questiondoesnotexist', 'question');
}
}
}
}
$category = $categories[$question->category];
+ $context = get_context_instance_by_id($category->contextid);
if (array_search($cap, $question_questioncaps)!== FALSE){
- if (!has_capability('moodle/question:'.$cap.'all', get_context_instance_by_id($category->contextid))){
+ if (!has_capability('moodle/question:'.$cap.'all', $context)){
if ($question->createdby == $USER->id){
- return has_capability('moodle/question:'.$cap.'mine', get_context_instance_by_id($category->contextid));
+ return has_capability('moodle/question:'.$cap.'mine', $context);
} else {
return false;
}
return true;
}
} else {
- return has_capability('moodle/question:'.$cap, get_context_instance_by_id($category->contextid));
+ return has_capability('moodle/question:'.$cap, $context);
}
}
}
return $question;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+
+ function delete_question($questionid, $contextid) {
global $DB;
$DB->delete_records("question_calculated", array("question" => $questionid));
}
}
$DB->delete_records("question_datasets", array("question" => $questionid));
- return true;
+
+ parent::delete_question($questionid, $contextid);
}
+
function test_response(&$question, &$state, $answer) {
$virtualqtype = $this->get_virtual_qtype();
return $virtualqtype->test_response($question, $state, $answer);
}
+
function compare_responses(&$question, $state, $teststate) {
$virtualqtype = $this->get_virtual_qtype();
$this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
$fs->move_area_files_to_new_context($oldcontextid,
- $newcontextid, 'qtype_numerical', 'instruction', $questionid);
+ $newcontextid, 'qtype_calculated', 'instruction', $questionid);
+ }
+
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ $fs->delete_area_files($contextid, 'qtype_calculated', 'instruction', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
$newcontextid, 'qtype_calculatedmulti', 'incorrectfeedback', $questionid);
}
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid, true);
+ $fs->delete_area_files($contextid, 'qtype_calculatedmulti', 'correctfeedback', $questionid);
+ $fs->delete_area_files($contextid, 'qtype_calculatedmulti', 'partiallycorrectfeedback', $questionid);
+ $fs->delete_area_files($contextid, 'qtype_calculatedmulti', 'incorrectfeedback', $questionid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
$itemid = reset($args);
$newcontextid, 'qtype_calculatedsimple', 'instruction', $questionid);
}
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ $fs->delete_area_files($contextid, 'qtype_calculatedsimple', 'instruction', $questionid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
$itemid = reset($args);
$this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
}
+ protected function delete_files($questionid, $contextid) {
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
if ($component == 'question' && $filearea == 'answerfeedback') {
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param integer $question->id
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
- $DB->delete_records("question_match", array("question" => $questionid));
- $DB->delete_records("question_match_sub", array("question" => $questionid));
- return true;
+ $DB->delete_records('question_match', array('question' => $questionid));
+ $DB->delete_records('question_match_sub', array('question' => $questionid));
+
+ parent::delete_question($questionid, $contextid);
}
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
}
}
+ protected function delete_files($questionid, $contextid) {
+ global $DB;
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+
+ $subquestionids = $DB->get_records_menu('question_match_sub',
+ array('question' => $questionid), 'id', 'id,1');
+ foreach ($subquestionids as $subquestionid => $notused) {
+ $fs->delete_area_files($contextid, 'qtype_match', 'subquestion', $subquestionid);
+ }
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
$DB->delete_records("question_multianswer", array("question" => $questionid));
- return true;
+
+ parent::delete_question($questionid, $contextid);
}
function get_correct_responses(&$question, &$state) {
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
- $DB->delete_records("question_multichoice", array("question" => $questionid));
- return true;
+ $DB->delete_records('question_multichoice', array('question' => $questionid));
+
+ parent::delete_question($questionid, $contextid);
}
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
$newcontextid, 'qtype_multichoice', 'incorrectfeedback', $questionid);
}
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid, true);
+ $fs->delete_area_files($contextid, 'qtype_multichoice', 'correctfeedback', $questionid);
+ $fs->delete_area_files($contextid, 'qtype_multichoice', 'partiallycorrectfeedback', $questionid);
+ $fs->delete_area_files($contextid, 'qtype_multichoice', 'incorrectfeedback', $questionid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
$itemid = reset($args);
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
- $DB->delete_records("question_numerical", array("question" => $questionid));
- $DB->delete_records("question_numerical_options", array("question" => $questionid));
- $DB->delete_records("question_numerical_units", array("question" => $questionid));
- return true;
+ $DB->delete_records('question_numerical', array('question' => $questionid));
+ $DB->delete_records('question_numerical_options', array('question' => $questionid));
+ $DB->delete_records('question_numerical_units', array('question' => $questionid));
+
+ parent::delete_question($questionid, $contextid);
}
+
/**
* This function has been reinserted in numerical/questiontype.php to simplify
* the separate rendering of number and unit
$newcontextid, 'qtype_numerical', 'instruction', $questionid);
}
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ $fs->delete_area_files($contextid, 'qtype_numerical', 'instruction', $questionid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
$itemid = reset($args);
$this->assertEqual($this->qtype->name(), 'numerical');
}
-// function test_get_question_options() {
-// }
-//
-// function test_get_numerical_units() {
-// }
-//
-// function test_get_default_numerical_unit() {
-// }
-//
-// function test_save_question_options() {
-// }
-//
-// function test_save_numerical_units() {
-// }
-//
-// function test_delete_question() {
-// }
-//
-// function test_compare_responses() {
-// }
-//
-// function test_test_response() {
-// }
-//
-// function test_check_response(){
-// }
-//
-// function test_grade_responses() {
-// }
-//
-// function test_get_correct_responses() {
-// }
-//
-// function test_get_all_responses() {
-// }
-
function test_get_tolerance_interval() {
$answer = new stdClass;
$answer->tolerance = 0.01;
}
/**
- * Deletes a question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
- global $CFG, $DB;
- $success = true;
+ * Deletes the question-type specific data when a question is deleted.
+ * @param integer $question the question being deleted.
+ * @param integer $contextid the context this quesiotn belongs to.
+ */
+ function delete_question($questionid, $contextid) {
+ global $DB;
+
+ $this->delete_files($questionid, $contextid);
$extra_question_fields = $this->extra_question_fields();
if (is_array($extra_question_fields)) {
$question_extension_table = array_shift($extra_question_fields);
- $success = $success && $DB->delete_records($question_extension_table,
+ $DB->delete_records($question_extension_table,
array($this->questionid_column_name() => $questionid));
}
$extra_answer_fields = $this->extra_answer_fields();
if (is_array($extra_answer_fields)) {
$answer_extension_table = array_shift($extra_answer_fields);
- $success = $success && $DB->delete_records_select($answer_extension_table,
+ $DB->delete_records_select($answer_extension_table,
"answerid IN (SELECT qa.id FROM {question_answers} qa WHERE qa.question = ?)", array($questionid));
}
- $success = $success && $DB->delete_records('question_answers', array('question' => $questionid));
-
- return $success;
+ $DB->delete_records('question_answers', array('question' => $questionid));
}
/**
/**
* Move all the files belonging to this question from one context to another.
- * @param object $question the question to move.
+ * @param integer $questionid the question being moved.
* @param integer $oldcontextid the context it is moving from.
* @param integer $newcontextid the context it is moving to.
*/
}
/**
- *
- * @param object $question the question to move.
+ * Move all the files belonging to this question's answers when the question
+ * is moved from one context to another.
+ * @param integer $questionid the question being moved.
* @param integer $oldcontextid the context it is moving from.
* @param integer $newcontextid the context it is moving to.
* @param boolean $answerstoo whether there is an 'answer' question area,
protected function move_files_in_answers($questionid, $oldcontextid, $newcontextid, $answerstoo = false) {
global $DB;
$fs = get_file_storage();
+
$answerids = $DB->get_records_menu('question_answers',
array('question' => $questionid), 'id', 'id,1');
foreach ($answerids as $answerid => $notused) {
}
}
+ /**
+ * Delete all the files belonging to this question.
+ * @param integer $questionid the question being deleted.
+ * @param integer $contextid the context the question is in.
+ */
+ protected function delete_files($questionid, $contextid) {
+ $fs = get_file_storage();
+ $fs->delete_area_files($contextid, 'question', 'questiontext', $questionid);
+ $fs->delete_area_files($contextid, 'question', 'generalfeedback', $questionid);
+ }
+
+ /**
+ * Delete all the files belonging to this question's answers.
+ * @param integer $questionid the question being deleted.
+ * @param integer $contextid the context the question is in.
+ * @param boolean $answerstoo whether there is an 'answer' question area,
+ * as well as an 'answerfeedback' one. Default false.
+ */
+ protected function delete_files_in_answers($questionid, $contextid, $answerstoo = false) {
+ global $DB;
+ $fs = get_file_storage();
+
+ $answerids = $DB->get_records_menu('question_answers',
+ array('question' => $questionid), 'id', 'id,1');
+ foreach ($answerids as $answerid => $notused) {
+ if ($answerstoo) {
+ $fs->delete_area_files($contextid, 'question', 'answer', $answerid);
+ }
+ $fs->delete_area_files($contextid, 'question', 'answerfeedback', $answerid);
+ }
+ }
+
function import_file($context, $component, $filearea, $itemid, $file) {
$fs = get_file_storage();
$record = new stdclass;
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
- $DB->delete_records("question_randomsamatch", array("question" => $questionid));
- return true;
+ $DB->delete_records('question_randomsamatch', array('question' => $questionid));
+
+ parent::delete_question($questionid, $contextid);
}
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
$this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
}
+ protected function delete_files($questionid, $contextid) {
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ }
+
function save_question_options($question) {
global $DB;
$result = new stdClass;
return true;
}
- /**
- * Deletes question from the question-type specific tables
- *
- * @return boolean Success/Failure
- * @param object $question The question being deleted
- */
- function delete_question($questionid) {
+ function delete_question($questionid, $contextid) {
global $DB;
- $DB->delete_records("question_truefalse", array("question" => $questionid));
- return true;
+ $DB->delete_records('question_truefalse', array('question' => $questionid));
+
+ parent::delete_question($questionid, $contextid);
}
function compare_responses($question, $state, $teststate) {
$this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
}
+ protected function delete_files($questionid, $contextid) {
+ parent::delete_files($questionid, $contextid);
+ $this->delete_files_in_answers($questionid, $contextid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
if ($component == 'question' && $filearea == 'answerfeedback') {