diff --git a/lib/questionlib.php b/lib/questionlib.php
index 389270109f2..30e043303aa 100644
--- a/lib/questionlib.php
+++ b/lib/questionlib.php
@@ -120,16 +120,6 @@ define('QUESTION_PREVIEW_POPUP_OPTIONS', 'scrollbars=yes&resizable=yes&width=700
define('QUESTION_ADAPTIVE', 1);
/**#@-*/
-/**#@+
- * Options used in forms that move files.
- */
-define('QUESTION_FILENOTHINGSELECTED', 0);
-define('QUESTION_FILEDONOTHING', 1);
-define('QUESTION_FILECOPY', 2);
-define('QUESTION_FILEMOVE', 3);
-define('QUESTION_FILEMOVELINKSONLY', 4);
-/**#@-*/
-
/**#@+
* Options for whether flags are shown/editable when rendering questions.
*/
@@ -718,7 +708,7 @@ function question_delete_course_category($category, $newcategory, $feedback=true
// added to a course, and then that course is moved to another category (MDL-14802).
$questionids = $DB->get_records_menu('question', array('category'=>$category->id), '', 'id,1');
if (!empty($questionids)) {
- if (!$rescueqcategory = question_save_from_deletion(implode(',', array_keys($questionids)),
+ if (!$rescueqcategory = question_save_from_deletion(array_keys($questionids),
get_parent_contextid($context), print_context_name($context), $rescueqcategory)) {
return false;
}
@@ -854,32 +844,57 @@ function question_delete_activity($cm, $feedback=true) {
function question_move_questions_to_category($questionids, $newcategoryid) {
global $DB, $QTYPES;
- $ids = explode(',', $questionids);
- foreach ($ids as $questionid) {
- $questionid = (int)$questionid;
- $params = array();
- $params[] = $questionid;
- $sql = 'SELECT q.*, c.id AS contextid, c.contextlevel, c.instanceid, c.path, c.depth
- FROM {question} q, {question_categories} qc, {context} c
- WHERE q.category=qc.id AND q.id=? AND qc.contextid=c.id';
- $question = $DB->get_record_sql($sql, $params);
- $category = $DB->get_record('question_categories', array('id'=>$newcategoryid));
- // process files
- $QTYPES[$question->qtype]->move_files($question, $category);
+ $newcontextid = $DB->get_field('question_categories', 'contextid',
+ array('id' => $newcategoryid));
+ list($questionidcondition, $params) = $DB->get_in_or_equal($questionids);
+ $questions = $DB->get_records_sql("
+ SELECT q.id, q.qtype, qc.contextid
+ FROM {question} q
+ JOIN {question_categories} qc ON q.category = qc.id
+ WHERE q.id $questionidcondition", $params);
+ foreach ($questions as $question) {
+ if ($newcontextid != $question->contextid) {
+ $QTYPES[$question->qtype]->move_files($question->id,
+ $question->contextid, $newcontextid);
+ }
}
-
// Move the questions themselves.
- $DB->set_field_select('question', 'category', $newcategoryid, "id IN ($questionids)");
+ $DB->set_field_select('question', 'category', $newcategoryid, "id $questionidcondition", $params);
// Move any subquestions belonging to them.
- $DB->set_field_select('question', 'category', $newcategoryid, "parent IN ($questionids)");
+ $DB->set_field_select('question', 'category', $newcategoryid, "parent $questionidcondition", $params);
// TODO Deal with datasets.
return true;
}
+/**
+ * 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, $QTYPES;
+
+ $questionids = $DB->get_records_menu('question',
+ array('category' => $categoryid), '', 'id,qtype');
+ foreach ($questionids as $questionid => $qtype) {
+ $QTYPES[$qtype]->move_files($questionid, $oldcontextid, $newcontextid);
+ }
+
+ $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);
+ }
+}
+
/**
* Given a list of ids, load the basic information about a set of questions from the questions table.
* The $join and $extrafields arguments can be used together to pull in extra data.
@@ -1850,37 +1865,11 @@ function print_question_icon($question, $return = false) {
}
/**
-* Returns a html link to the question image if there is one
-*
- * @global object
- * @global object
-* @return string The html image tag or the empy string if there is no image.
-* @param object $question The question object
-*/
-function get_question_image($question) {
- global $CFG, $DB;
- $img = '';
-
- if (!$category = $DB->get_record('question_categories', array('id'=>$question->category))) {
- print_error('invalidcategory');
- }
- $coursefilesdir = get_filesdir_from_context(get_context_instance_by_id($category->contextid));
-
- if ($question->image) {
-
- if (substr(strtolower($question->image), 0, 7) == 'http://') {
- $img .= $question->image;
-
- } else {
- require_once($CFG->libdir .'/filelib.php');
- $img = get_file_url("$coursefilesdir/{$question->image}");
- }
- }
- return $img;
-}
-
-/**
- * @global array
+ * @param $question
+ * @param $state
+ * @param $prefix
+ * @param $cmoptions
+ * @param $caption
*/
function question_print_comment_fields($question, $state, $prefix, $cmoptions, $caption = '') {
global $QTYPES;
@@ -2826,117 +2815,6 @@ function question_require_capability_on($question, $cap){
return true;
}
-/**
- * @global object
- */
-function question_file_links_base_url($courseid){
- global $CFG;
- $baseurl = preg_quote("$CFG->wwwroot/file.php", '!');
- $baseurl .= '('.preg_quote('?file=', '!').')?';//may or may not
- //be using slasharguments, accept either
- $baseurl .= "/$courseid/";//course directory
- return $baseurl;
-}
-
-/**
- * Find all course / site files linked to in a piece of html.
- * @global object
- * @param string html the html to search
- * @param int course search for files for courseid course or set to siteid for
- * finding site files.
- * @return array files with keys being files.
- */
-function question_find_file_links_from_html($html, $courseid){
- global $CFG;
- $baseurl = question_file_links_base_url($courseid);
- $searchfor = '!'.
- '(<\s*(a|img)\s[^>]*(href|src)\s*=\s*")'.$baseurl.'([^"]*)"'.
- '|'.
- '(<\s*(a|img)\s[^>]*(href|src)\s*=\s*\')'.$baseurl.'([^\']*)\''.
- '!i';
- $matches = array();
- $no = preg_match_all($searchfor, $html, $matches);
- if ($no){
- $rawurls = array_filter(array_merge($matches[5], $matches[10]));//array_filter removes empty elements
- //remove any links that point somewhere they shouldn't
- foreach (array_keys($rawurls) as $rawurlkey){
- if (!$cleanedurl = question_url_check($rawurls[$rawurlkey])){
- unset($rawurls[$rawurlkey]);
- } else {
- $rawurls[$rawurlkey] = $cleanedurl;
- }
-
- }
- $urls = array_flip($rawurls);// array_flip removes duplicate files
- // and when we merge arrays will continue to automatically remove duplicates
- } else {
- $urls = array();
- }
- return $urls;
-}
-
-/**
- * Check that url doesn't point anywhere it shouldn't
- *
- * @global object
- * @param $url string relative url within course files directory
- * @return mixed boolean false if not OK or cleaned URL as string if OK
- */
-function question_url_check($url){
- global $CFG;
- if ((substr(strtolower($url), 0, strlen($CFG->moddata)) == strtolower($CFG->moddata)) ||
- (substr(strtolower($url), 0, 10) == 'backupdata')){
- return false;
- } else {
- return clean_param($url, PARAM_PATH);
- }
-}
-
-/**
- * Find all course / site files linked to in a piece of html.
- *
- * @global object
- * @param string html the html to search
- * @param int course search for files for courseid course or set to siteid for
- * finding site files.
- * @return array files with keys being files.
- */
-function question_replace_file_links_in_html($html, $fromcourseid, $tocourseid, $url, $destination, &$changed){
- global $CFG;
- require_once($CFG->libdir .'/filelib.php');
- $tourl = get_file_url("$tocourseid/$destination");
- $fromurl = question_file_links_base_url($fromcourseid).preg_quote($url, '!');
- $searchfor = array('!(<\s*(a|img)\s[^>]*(href|src)\s*=\s*")'.$fromurl.'(")!i',
- '!(<\s*(a|img)\s[^>]*(href|src)\s*=\s*\')'.$fromurl.'(\')!i');
- $newhtml = preg_replace($searchfor, '\\1'.$tourl.'\\5', $html);
- if ($newhtml != $html){
- $changed = true;
- }
- return $newhtml;
-}
-
-/**
- * @global object
- */
-function get_filesdir_from_context($context){
- global $DB;
-
- switch ($context->contextlevel){
- case CONTEXT_COURSE :
- $courseid = $context->instanceid;
- break;
- case CONTEXT_MODULE :
- $courseid = $DB->get_field('course_modules', 'course', array('id'=>$context->instanceid));
- break;
- case CONTEXT_COURSECAT :
- case CONTEXT_SYSTEM :
- $courseid = SITEID;
- break;
- default :
- print_error('invalidcontext');
- }
- return $courseid;
-}
/**
* Get the real state - the correct question id and answer - for a random
* question.
@@ -2944,7 +2822,7 @@ function get_filesdir_from_context($context){
* @return mixed return integer real question id or false if there was an
* error..
*/
-function question_get_real_state($state){
+function question_get_real_state($state) {
global $OUTPUT;
$realstate = clone($state);
$matches = array();
diff --git a/question/category_class.php b/question/category_class.php
index ac5903fac54..46842d43c09 100644
--- a/question/category_class.php
+++ b/question/category_class.php
@@ -38,24 +38,6 @@ class question_category_list extends moodle_list {
public function get_records() {
$this->records = get_categories_for_contexts($this->context->id, $this->sortby);
}
- public function process_actions($left, $right, $moveup, $movedown, $moveupcontext, $movedowncontext, $tocontext){
- global $CFG;
- //parent::procces_actions redirects after any action
- parent::process_actions($left, $right, $moveup, $movedown);
- if ($tocontext == $this->context->id){
- //only called on toplevel list
- if ($moveupcontext){
- $cattomove = $moveupcontext;
- $totop = 0;
- } elseif ($movedowncontext){
- $cattomove = $movedowncontext;
- $totop = 1;
- }
- $toparent = "0,{$this->context->id}";
- $url = new moodle_url('/question/contextmove.php?', $this->pageurl->params() + compact('cattomove', 'totop', 'toparent'));
- redirect($url);
- }
- }
}
class question_category_list_item extends list_item {
@@ -87,12 +69,13 @@ class question_category_list_item extends list_item {
/// Each section adds html to be displayed as part of this list item
$questionbankurl = new moodle_url("/question/edit.php", ($this->parentlist->pageurl->params() + array('category'=>"$category->id,$category->contextid")));
- $catediturl = $this->parentlist->pageurl->out(true, array('edit'=>$this->id));
+ $catediturl = $this->parentlist->pageurl->out(true, array('edit' => $this->id));
$item = "edit}\" href=\"$catediturl\">".$category->name ." ".'('.$category->questioncount.')';
$item .= ' '. $category->info;
- if (count($this->parentlist->records)!=1){ // don't allow delete if this is the last category in this context.
+ // don't allow delete if this is the last category in this context.
+ if (count($this->parentlist->records) != 1) {
$item .= '
';
}
@@ -374,11 +357,9 @@ class question_category_object {
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);
- }
+ $questionids = $DB->get_records_select_menu('question',
+ 'category = ? AND (parent = 0 OR parent = id)', array($oldcat), '', 'id,1');
+ question_move_questions_to_category($questionids, $newcat);
}
/**
@@ -439,7 +420,7 @@ class question_category_object {
require_capability('moodle/question:managecategory', $fromcontext);
// If moving to another context, check permissions some more.
- if ($oldcat->contextid != $tocontextid){
+ if ($oldcat->contextid != $tocontextid) {
$tocontext = get_context_instance_by_id($tocontextid);
require_capability('moodle/question:managecategory', $tocontext);
}
@@ -450,7 +431,7 @@ class question_category_object {
$cat->name = $newname;
$cat->info = $newinfo;
$cat->parent = $parentid;
- // We don't change $cat->contextid here, if necessary we redirect to contextmove.php later.
+ $cat->contextid = $tocontextid;
$DB->update_record('question_categories', $cat);
// If the category name has changed, rename any random questions in that category.
@@ -464,41 +445,11 @@ class question_category_object {
$DB->set_field_select('question', 'name', $randomqname, $where, array($cat->id, '1'));
}
- // Then redirect to an appropriate place.
- if ($oldcat->contextid == $tocontextid) { // not moving contexts
- redirect($this->pageurl);
- } else {
- $url = new moodle_url('/question/contextmove.php', ($this->pageurl->params() + array('cattomove' => $updateid, 'toparent'=>$newparent)));
- redirect($url);
+ if ($oldcat->contextid != $tocontextid) {
+ // Moving to a new context. Must move files belonging to questions.
+ question_move_category_to_context($cat->id, $oldcat->contextid, $tocontextid);
}
+
+ redirect($this->pageurl);
}
-
- public function move_question_from_cat_confirm($fromcat, $fromcourse, $tocat=null, $question=null){
- global $QTYPES, $DB;
- if (!$question){
- $questions[] = $question;
- } else {
- $questions = $DB->get_records('question', array('category' => $tocat->id));
- }
- $urls = array();
- foreach ($questions as $question){
- $urls = array_merge($urls, $QTYPES[$question->qtype]->find_file_links_in_question($question));
- }
- if ($fromcourse){
- $append = 'tocourse';
- } else {
- $append = 'tosite';
- }
- if ($tocat){
- echo '
'.get_string('needtomovethesefilesincat','question').'
';
- } else {
- echo ''.get_string('needtomovethesefilesinquestion','question').'
';
- }
- }
-
-
-
-
}
-
-
diff --git a/question/contextmove.php b/question/contextmove.php
deleted file mode 100644
index 88544546638..00000000000
--- a/question/contextmove.php
+++ /dev/null
@@ -1,219 +0,0 @@
-dirroot."/question/editlib.php");
- require_once($CFG->dirroot."/question/contextmove_form.php");
-
- //TODO: MDL-16094
- throw new coding_exception('contextmove.php was not converted to new file api yet, sorry - see MDL-16094');
-
- list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) =
- question_edit_setup('categories', '/question/contextmove.php');
-
- // get values from form for actions on this page
- $toparent = required_param('toparent', PARAM_SEQUENCE);
- $cattomove = required_param('cattomove', PARAM_INT);
- $totop = optional_param('totop', 0, PARAM_INT); // optional param moves category to top of peers. Default is
- //to add it to the bottom.
-
-
-
- $onerrorurl = new moodle_url('/question/category.php', $thispageurl->params());
- list($toparent, $contextto) = explode(',', $toparent);
- if (!empty($toparent)){//not top level category, make it a child of $toparent
- if (!$toparent = $DB->get_record('question_categories', array('id' => $toparent))){
- print_error('invalidcategoryidforparent', 'question', $onerrorurl);
- }
- $contextto = $toparent->contextid;
- } else {
- $toparent = new stdClass();
- $toparent->id = 0;
- $toparent->contextid = $contextto;
- }
- if (!$cattomove = $DB->get_record('question_categories', array('id' => $cattomove))){
- print_error('invalidcategoryidtomove', 'question', $onerrorurl);
- }
- if ($cattomove->contextid == $contextto){
- print_error('contexterror', '', $onerrorurl);
- }
- $cattomove->categorylist = question_categorylist($cattomove->id);
-
- $thispageurl->params(array('cattomove'=>$cattomove->id,
- 'toparent'=>"{$toparent->id},{$toparent->contextid}",
- 'totop'=>$totop));
-
- $contextfrom = get_context_instance_by_id($cattomove->contextid);
- $contextto = get_context_instance_by_id($contextto);
- $contexttostring = print_context_name($contextto);
-
- require_capability('moodle/question:managecategory', $contextfrom);
- require_capability('moodle/question:managecategory', $contextto);
-
-
- $fromcoursefilesid = get_filesdir_from_context($contextfrom);//siteid or courseid
- $tocoursefilesid = get_filesdir_from_context($contextto);//siteid or courseid
- if ($fromcoursefilesid != $tocoursefilesid){
- list($usql, $params) = $DB->get_in_or_equal(explode(',', $cattomove->categorylist));
- $questions = $DB->get_records_select('question', "category $usql", $params);
- $urls = array();
- if ($questions){
- foreach ($questions as $id => $question){
- $QTYPES[$questions[$id]->qtype]->get_question_options($questions[$id]);
- $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
- }
- }
- ksort($urls);
- } else {
- $urls = array();
- }
- $brokenurls = array();
- foreach (array_keys($urls) as $url){
- if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
- $brokenurls[] = $url;
- }
- }
- if ($fromcoursefilesid == SITEID){
- $fromareaname = get_string('filesareasite', 'question');
- } else {
- $fromareaname = get_string('filesareacourse', 'question');
- }
- if ($tocoursefilesid == SITEID){
- $toareaname = get_string('filesareasite', 'question');
- } else {
- $toareaname = get_string('filesareacourse', 'question');
- }
- $contextmoveform = new question_context_move_form($thispageurl,
- compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
- 'fromcoursefilesid', 'tocoursefilesid'));
- if ($contextmoveform->is_cancelled()){
- $thispageurl->remove_params('cattomove', 'toparent', 'totop');
- redirect(new moodle_url("/question/category.php".$thispageurl->params()));
- }elseif ($moveformdata = $contextmoveform->get_data()) {
- if (isset($moveformdata->urls) && is_array($moveformdata->urls)){
- check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
- $flipurls = array_keys($urls);
- foreach ($moveformdata->urls as $key => $urlaction){
- $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
- $destination = $flipurls[$key];
- if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
- // Ensure the target folder exists.
- check_dir_exists(dirname($CFG->dataroot."/$tocoursefilesid/".$destination), true);
-
- // Then make sure the destination file name does not exist. If it does, change the name to be unique.
- while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
- $matches = array();
- //check for '_'. copyno after filename, before extension.
- if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
- $copyno = $matches[1]+1;
- } else {
- $copyno = 1;
- }
- //replace old copy no with incremented one.
- $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
- }
- }
- switch ($urlaction){
- case QUESTION_FILECOPY :
- if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
- print_error('errorfilecannotbecopied', 'question', $onerrorurl, $source);
- }
- break;
- case QUESTION_FILEMOVE :
- if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
- print_error('errorfilecannotbemoved', 'question', $onerrorurl, $source);
- }
- break;
- case QUESTION_FILEDONOTHING :
- case QUESTION_FILEMOVELINKSONLY :
- break;
- default :
- print_error('invalidaction', '', $onerrorurl);
- }
- switch ($urlaction){
- //now search and replace urls in questions.
- case QUESTION_FILECOPY :
- case QUESTION_FILEMOVE :
- case QUESTION_FILEMOVELINKSONLY :
- $url = $flipurls[$key];
- $questionids = array_unique($urls[$url]);
- foreach ($questionids as $questionid){
- $question = $questions[$questionid];
- $QTYPES[$question->qtype]->replace_file_links($question, $fromcoursefilesid, $tocoursefilesid, $url, $destination);
- }
- break;
- case QUESTION_FILEDONOTHING :
- default :
- break;
- }
-
-
- }
- }
-
- //adjust sortorder before we make the cat a peer of it's new peers
- $peers = $DB->get_records_select_menu('question_categories',
- 'contextid = ? AND parent = ?', array($toparent->contextid, $toparent->id),
- 'sortorder ASC', 'id, 1');
- $peers = array_keys($peers);
- if ($totop){
- array_unshift($peers, $cattomove->id);
- } else {
- $peers[] = $cattomove->id;
- }
- $sortorder = 0;
- foreach ($peers as $peer) {
- $DB->set_field('question_categories', "sortorder", $sortorder, array("id" => $peer));
- $sortorder++;
- }
- //now move category
- $cat = new stdClass();
- $cat->id = $cattomove->id;
- $cat->parent = $toparent->id;
- //set context of category we are moving and all children also!
- list($usql, $params) = $DB->get_in_or_equal(explode(',', $cattomove->categorylist));
- $params = array_merge(array($contextto->id), $params);
-
- $DB->execute("UPDATE {question_categories} SET contextid = ? WHERE id $usql", $params);
- //finally set the new parent id
- $DB->update_record("question_categories", $cat);
- $thispageurl->remove_params('cattomove', 'toparent', 'totop');
- $url = new moodle_url('/question/category.php', ($thispageurl->params() + array('cat'=>"{$cattomove->id},{$contextto->id}")));
- redirect($url);
- }
-
- $streditingcategories = get_string('editcategories', 'quiz');
-
- $PAGE->set_url($thispageurl->out());
- $PAGE->navbar->add($streditingcategories, $thispageurl->out());
- $PAGE->navbar->add(get_string('movingcategory', 'question'));
- $PAGE->set_heading($COURSE->fullname);
- echo $OUTPUT->header();
-
- //parameter for get_string
- $cattomove->contextto = $contexttostring;
- if (count($urls)){
- $defaults = array();
- for ($default_key = 0; $default_key < count($urls); $default_key++){
- $defaults['urls'][$default_key] = QUESTION_FILECOPY;
- }
- $contextmoveform->set_data($defaults);
- //some parameters for get_string
- $cattomove->urlcount = count($urls);
- $cattomove->toareaname = $toareaname;
- $cattomove->fromareaname = $fromareaname;
-
- echo $OUTPUT->box(get_string('movingcategoryandfiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
- } else {
- echo $OUTPUT->box(get_string('movingcategorynofiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
- }
- $contextmoveform->display();
- echo $OUTPUT->footer();
-
diff --git a/question/contextmove_form.php b/question/contextmove_form.php
deleted file mode 100644
index 9a16a9730f7..00000000000
--- a/question/contextmove_form.php
+++ /dev/null
@@ -1,107 +0,0 @@
-libdir.'/formslib.php');
-
-class question_context_move_form extends moodleform {
-
- function definition() {
- global $CFG, $OUTPUT;
- $mform =& $this->_form;
-
-//--------------------------------------------------------------------------------
- $urls = $this->_customdata['urls'];
- $fromareaname = $this->_customdata['fromareaname'];
- $toareaname = $this->_customdata['toareaname'];
- $fileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
- QUESTION_FILECOPY=>get_string('copy', 'question', $fromareaname),
- QUESTION_FILEMOVE=>get_string('move', 'question', $fromareaname),
- QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
- $brokenfileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
- QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
- $brokenurls = $this->_customdata['brokenurls'];
- if (count($urls)){
-
- $mform->addElement('header','general', get_string('filestomove', 'question', $toareaname));
-
- $i = 0;
- foreach (array_keys($urls) as $url){
- $icontype = mimeinfo('type', $url);
- $img = "
pix_url(file_extension_icon($url)) . "\" class=\"icon\" alt=\"$icontype\" />";
- if (in_array($url, $brokenurls)){
- $mform->addElement('select', "urls[$i]", $img.$url, $brokenfileoptions);
- } else {
- $mform->addElement('select', "urls[$i]", $img.$url, $fileoptions);
- }
- $i++;
- }
-
- }
- if (count($brokenurls)){
- $mform->addElement('advcheckbox','ignorebroken', get_string('ignorebroken', 'question'));
- }
- //--------------------------------------------------------------------------------
- $this->add_action_buttons(true, get_string('movecategory', 'question'));
-
- }
-
- function validation($data, $files) {
- $errors = parent::validation($data, $files);
- $tocoursefilesid = $this->_customdata['tocoursefilesid'];
- $fromcoursefilesid = $this->_customdata['fromcoursefilesid'];
- if (isset($data['urls']) && (count($data['urls']))){
- foreach ($data['urls'] as $key => $urlaction){
- switch ($urlaction){
- case QUESTION_FILEMOVE :
- if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $fromcoursefilesid))){
- $errors["urls[$key]"] = get_string('filecantmovefrom', 'question');
- }
- //no break; COPY check is also applied to MOVE action
- case QUESTION_FILECOPY :
- if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $tocoursefilesid))){
- $errors["urls[$key]"] = get_string('filecantmoveto', 'question');
- }
- break;
- case QUESTION_FILEMOVELINKSONLY :
- case QUESTION_FILEDONOTHING :
- break;
- }
- }
- }
- //check that there hasn't been any changes in files between time form was displayed
- //and now when it has been submitted.
- if (isset($data['urls']) &&
- (count($data['urls'])
- != count($this->_customdata['urls']))){
- $errors['urls[0]'] = get_string('errorfileschanged', 'question');
- }
- return $errors;
- }
- /*
- * We want these errors to show up on first loading the form which is not the default for
- * validation method which is not run until submission.
- */
- function definition_after_data(){
- $mform = $this->_form;
- $brokenurls = $this->_customdata['brokenurls'];
- if (count($brokenurls)){
- $ignoreval = $mform->getElementValue('ignorebroken');
- if (!$ignoreval){
- $urls = $this->_customdata['urls'];
- $i = 0;
- foreach (array_keys($urls) as $url){
- if (in_array($url, $brokenurls)){
- $mform->setElementError("urls[$i]", get_string('broken', 'question'));
- } else {
- $mform->setElementError("urls[$i]", '');
- }
- $i++;
- }
- }
- }
- }
-}
-
diff --git a/question/contextmoveq.php b/question/contextmoveq.php
deleted file mode 100644
index 0ad72f73137..00000000000
--- a/question/contextmoveq.php
+++ /dev/null
@@ -1,224 +0,0 @@
-dirroot.'/question/contextmoveq_form.php');
-
-//TODO: MDL-16094
-throw new coding_exception('contextmoveq.php was not converted to new file api yet, sorry - see MDL-16094');
-
-$ids = required_param('ids', PARAM_SEQUENCE); // question ids
-
-if (!$cmid = optional_param('cmid', 0, PARAM_INT)){
- $courseid = required_param('courseid', PARAM_INT);
-}
-
-$tocatid = required_param('tocatid', PARAM_INT);
-$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
-
-$thispageurl = new moodle_url('/question/contextmoveq.php');
-$thispageurl->params(compact('tocatid', 'ids', 'returnurl'));
-
-if ($cmid){
- list($module, $cm) = get_module_from_cmid($cmid);
- require_login($cm->course, false, $cm);
- $thiscontext = get_context_instance(CONTEXT_MODULE, $cmid);
- if (!$returnurl) {
- $returnurl = "{$CFG->wwwroot}/question/edit.php?cmid={$cm->id}";
- }
- $thispageurl->param('cmid', $cmid);
-} elseif ($courseid) {
- require_login($courseid, false);
- $thiscontext = get_context_instance(CONTEXT_COURSE, $courseid);
- $module = null;
- $cm = null;
- if (!$returnurl) {
- $returnurl = "{$CFG->wwwroot}/question/edit.php?courseid={$COURSE->id}";
- }
- $thispageurl->param('courseid', $COURSE->id);
-} else {
- print_error('missingcourseorcmid', 'question');
-}
-$contexts = new question_edit_contexts($thiscontext);
-
-list($usql, $params) = $DB->get_in_or_equal(explode(',', $ids));
-
-if (!$questions = $DB->get_records_sql("SELECT q.*, c.contextid FROM {question} q, {question_categories} c WHERE q.id $usql AND c.id = q.category", $params)) {
- print_error('questiondoesnotexist', 'question', $returnurl);
-}
-if (!$tocat = $DB->get_record('question_categories', array('id' => $tocatid))){
- print_error('categorydoesnotexist', 'question', $returnurl);
-}
-$tocat->context = get_context_instance_by_id($tocat->contextid);
-require_capability('moodle/question:add', $tocat->context);
-$tocoursefilesid = get_filesdir_from_context($tocat->context);
-$urls = array();
-
-if ($tocoursefilesid == SITEID){
- $toareaname = get_string('filesareasite', 'question');
-} else {
- $toareaname = get_string('filesareacourse', 'question');
-}
-$fromcoursefilesid = 0;
-foreach (array_keys($questions) as $id){
- question_require_capability_on($questions[$id], 'move');
- get_question_options($questions[$id]);
- $questions[$id]->context = get_context_instance_by_id($questions[$id]->contextid);
- $thisfilesid = get_filesdir_from_context($questions[$id]->context);
- if ($fromcoursefilesid && $thisfilesid != $fromcoursefilesid){
- print_error('cannotmovequestion', 'question');
- } else {
- $fromcoursefilesid = $thisfilesid;
- }
- if ($tocoursefilesid != $fromcoursefilesid){
- $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
- }
-}
-
-$brokenurls = array();
-foreach (array_keys($urls) as $url){
- if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
- $brokenurls[] = $url;
- }
-}
-if ($fromcoursefilesid == SITEID){
- $fromareaname = get_string('filesareasite', 'question');
-} else {
- $fromareaname = get_string('filesareacourse', 'question');
-}
-
-$contextmoveform = new question_context_move_question_form($thispageurl,
- compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
- 'fromcoursefilesid', 'tocoursefilesid'));
-if ($contextmoveform->is_cancelled()){
- redirect($returnurl);
-}elseif ($moveformdata = $contextmoveform->get_data()) {
- if (isset($moveformdata->urls) && is_array($moveformdata->urls)){
- check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
- $flipurls = array_keys($urls);
- //actions on files
- foreach ($moveformdata->urls as $key => $urlaction){
- $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
- $destination = $flipurls[$key];
- if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
- // Ensure the target folder exists.
- check_dir_exists(dirname($CFG->dataroot."/$tocoursefilesid/".$destination), true);
-
- // Then make sure the destination file name does not exist. If it does, change the name to be unique.
- while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
- $matches = array();
- //check for '_'. copyno after filename, before extension.
- if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
- $copyno = $matches[1]+1;
- } else {
- $copyno = 1;
- }
- //replace old copy no with incremented one.
- $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
- }
- }
- switch ($urlaction){
- case QUESTION_FILECOPY :
- if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
- print_error('errorfilecannotbecopied', 'question', $returnurl, $source);
- }
- break;
- case QUESTION_FILEMOVE :
- if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
- print_error('errorfilecannotbemoved', 'question', $returnurl, $source);
- }
- break;
- case QUESTION_FILEMOVELINKSONLY :
- case QUESTION_FILEDONOTHING :
- break;
- default :
- print_error('invalidaction', '', $returnurl);
- }
- //now search and replace urls in questions.
- switch ($urlaction){
- case QUESTION_FILECOPY :
- case QUESTION_FILEMOVE :
- case QUESTION_FILEMOVELINKSONLY :
- $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 :
- print_error('invalidaction', '', $returnurl);
- break;
- }
-
-
- }
- }
-
-/// Now move questions.
- if (!question_move_questions_to_category($ids, $tocat->id)) {
- print_error('errormovingquestions', 'question', $returnurl, $ids);
- }
- if ($returnurl) {
- $returnurl = new moodle_url('/' . $returnurl);
- }
- redirect($returnurl);
-}
-
-$streditingcategories = get_string('editcategories', 'quiz');
-$strmovingquestions = get_string('movingquestions', 'question');
-$PAGE->set_url($thispageurl->out());
-$PAGE->navbar->add($strmovingquestions);
-$PAGE->set_title($strmovingquestions);
-$PAGE->set_heading($COURSE->fullname);
-echo $OUTPUT->header();
-
-//parameter for get_string
-$questionsstr = new stdClass();
-$questionsstr->tocontext = print_context_name($tocat->context);
-$questionsstr->fromareaname = $fromareaname;
-
-//comma seperated string "'xx', 'cx', 'sdf' and 'fgdhfg'"
-$questionnamestojoin = array();
-foreach ($questions as $question){
- $questionnamestojoin[] = $question->name;
-}
-$tojoincount = count($questionnamestojoin);
-
-if ($tojoincount > 1){
- $a = new stdClass();
- $a->one = $questionnamestojoin[$tojoincount -2].'"';
- $a->two = '"'.$questionnamestojoin[$tojoincount -1];
- $questionnamestojoin[$tojoincount -2] = get_string('and', '', $a);
- unset($questionnamestojoin[$tojoincount -1]);
-}
-$questionsstr->questions = '"'.join($questionnamestojoin, '", "').'"';
-
-if (count($urls)){
- $defaults = array();
- for ($default_key = 0; $default_key < count($urls); $default_key++){
- $defaults['urls'][$default_key] = QUESTION_FILECOPY;
- }
- $contextmoveform->set_data($defaults);
-
- //some parameters for get_string
- $questionsstr->urlcount = count($urls);
-
- $questionsstr->toareaname = $toareaname;
-
- echo $OUTPUT->box(get_string('movingquestionsandfiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
-} else {
- echo $OUTPUT->box(get_string('movingquestionsnofiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
-}
-$contextmoveform->display();
-echo $OUTPUT->footer();
-
diff --git a/question/contextmoveq_form.php b/question/contextmoveq_form.php
deleted file mode 100644
index 2af39a52a93..00000000000
--- a/question/contextmoveq_form.php
+++ /dev/null
@@ -1,111 +0,0 @@
-libdir.'/formslib.php');
-
-class question_context_move_question_form extends moodleform {
-
- function definition() {
- global $CFG, $OUTPUT;
- $mform =& $this->_form;
-
-//--------------------------------------------------------------------------------
- $urls = $this->_customdata['urls'];
- $fromareaname = $this->_customdata['fromareaname'];
- $toareaname = $this->_customdata['toareaname'];
- $fileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
- QUESTION_FILECOPY=>get_string('copy', 'question', $fromareaname),
- QUESTION_FILEMOVE=>get_string('move', 'question', $fromareaname),
- QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
- $brokenfileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
- QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
-
- $brokenurls = $this->_customdata['brokenurls'];
- if (count($urls)){
-
- $mform->addElement('header','general', get_string('filestomove', 'question', $toareaname));
-
- $i = 0;
- foreach (array_keys($urls) as $url){
- $icontype = mimeinfo('type', $url);
- $img = "
pix_url(file_extension_icon($url)) . "\" class=\"icon\" alt=\"$icontype\" />";
- if (in_array($url, $brokenurls)){
- $mform->addElement('select', "urls[$i]", $img.$url, $brokenfileoptions);
- } else {
- $mform->addElement('select', "urls[$i]", $img.$url, $fileoptions);
- }
- $i++;
- }
-
- }
- if (count($brokenurls)){
- $mform->addElement('advcheckbox','ignorebroken', get_string('ignorebroken', 'question'));
- }
-//--------------------------------------------------------------------------------
- $this->add_action_buttons(true, get_string('moveq', 'question'));
- }
-
- function validation($data, $files) {
- $errors = parent::validation($data, $files);
- $tocoursefilesid = $this->_customdata['tocoursefilesid'];
- $fromcoursefilesid = $this->_customdata['fromcoursefilesid'];
- if (isset($data['urls']) && (count($data['urls']))){
- foreach ($data['urls'] as $key => $urlaction){
- switch ($urlaction){
- case QUESTION_FILEMOVE :
- if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $fromcoursefilesid))){
- $errors["urls[$key]"] = get_string('filecantmovefrom', 'question');
- }
- case QUESTION_FILECOPY :
- if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $tocoursefilesid))){
- $errors["urls[$key]"] = get_string('filecantmoveto', 'question');
- }
- break;
- case QUESTION_FILEMOVELINKSONLY :
- case QUESTION_FILEDONOTHING :
- break;
- }
- }
- }
- //check that there hasn't been any changes in files between time form was displayed
- //and now when it has been submitted.
- if (isset($data['urls']) &&
- (count($data['urls'])
- != count($this->_customdata['urls']))){
- $errors['urls[0]'] = get_string('errorfileschanged', 'question');
-
- }
- return $errors;
- }
- /*
- * We want these errors to show up on first loading the form which is not the default for
- * validation method which is not run until submission.
- */
- function definition_after_data(){
- static $done = false;
- if (!$done){
- $mform = $this->_form;
- $brokenurls = $this->_customdata['brokenurls'];
- if (count($brokenurls)){
- $ignoreval = $mform->getElementValue('ignorebroken');
- if (!$ignoreval){
- $urls = $this->_customdata['urls'];
- $i = 0;
- foreach (array_keys($urls) as $url){
- if (in_array($url, $brokenurls)){
- $mform->setElementError("urls[$i]", get_string('broken', 'question'));
- } else {
- $mform->setElementError("urls[$i]", '');
- }
- $i++;
- }
- }
- }
- $done = true;
- }
- }
-}
-
diff --git a/question/editlib.php b/question/editlib.php
index ba51bbb93c9..41bcaee1086 100644
--- a/question/editlib.php
+++ b/question/editlib.php
@@ -1385,7 +1385,8 @@ class question_bank_view {
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
+ 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))) {
@@ -1403,38 +1404,18 @@ class question_bank_view {
}
if ($questionids) {
list($usql, $params) = $DB->get_in_or_equal($questionids);
- $sql = "SELECT q.*, c.contextid FROM {question} q, {question_categories} c WHERE q.id $usql AND c.id = q.category";
- if (!$questions = $DB->get_records_sql($sql, $params)){
- print_error('questiondoesnotexist', 'question', $pageurl->out());
- }
- $checkforfiles = false;
+ $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){
- //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 = $this->baseurl->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 {
- $returnurl = str_replace($CFG->wwwroot . '/', '', $returnurl);
- $movecontexturl = new moodle_url('/question/contextmoveq.php',
- array('returnurl' => $returnurl,
- 'ids' => implode(',', $questionids),
- 'tocatid' => $tocategoryid));
- if (!empty($cm->id)){
- $movecontexturl->param('cmid', $cm->id);
- } else {
- $movecontexturl->param('courseid', $this->course->id);
- }
- redirect($movecontexturl);
}
+ question_move_questions_to_category($questionids, $tocategory->id);
+ redirect($this->baseurl->out(false,
+ array('category' => "$tocategoryid,$contextid")));
}
}
diff --git a/question/question.php b/question/question.php
index 8402cbb9eef..efdb1f62da8 100644
--- a/question/question.php
+++ b/question/question.php
@@ -211,7 +211,7 @@ if ($mform->is_cancelled()){
}
redirect($returnurl->out(false));
}
-} elseif ($fromform = $mform->get_data()) {
+} else if ($fromform = $mform->get_data()) {
/// If we are saving as a copy, break the connection to the old question.
if (!empty($fromform->makecopy)) {
$question->id = 0;
@@ -237,36 +237,27 @@ if ($mform->is_cancelled()){
question_require_capability_on($question, 'move');
}
- /// Ensure we redirect back to the category the question is being saved into.
+ // Ensure we redirect back to the category the question is being saved into.
$returnurl->param('category', $fromform->category);
- /// Call the appropriate method.
if ($movecontext) {
+ // We are just moving the question to a different context.
list($tocatid, $tocontextid) = explode(',', $fromform->categorymoveto);
- $tocontext = get_context_instance_by_id($tocontextid);
- require_capability('moodle/question:add', $tocontext);
- if (get_filesdir_from_context($categorycontext) != get_filesdir_from_context($tocontext)){
- $movecontexturl = new moodle_url('/question/contextmoveq.php', array(
- 'returnurl' => str_replace($CFG->wwwroot, '', $returnurl->out(false)),
- 'ids' => $question->id,
- 'tocatid' => $tocatid));
- if ($cmid){
- $movecontexturl->param('cmid', $cmid);
- } else {
- $movecontexturl->param('courseid', $courseid);
- }
- redirect($movecontexturl);
+ require_capability('moodle/question:add', get_context_instance_by_id($tocontextid));
+ question_move_questions_to_category(array($question->id), $tocatid);
+
+ } else {
+ // We are acutally saving the question.
+ $question = $QTYPES[$question->qtype]->save_question($question, $fromform, $COURSE, $wizardnow, true);
+ 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);
}
}
- $question = $QTYPES[$question->qtype]->save_question($question, $fromform, $COURSE, $wizardnow, true);
- // a wizardpage from multipe pages questiontype like calculated may not allow editing the question tags
- if (!empty($CFG->usetags) && isset($fromform->tags)) {
- require_once($CFG->dirroot.'/tag/lib.php');
- tag_set('question', $question->id, $fromform->tags);
- }
-
- if (($QTYPES[$question->qtype]->finished_edit_wizard($fromform)) || $movecontext){
+ if (($QTYPES[$question->qtype]->finished_edit_wizard($fromform)) || $movecontext) {
if ($inpopup) {
echo $OUTPUT->notification(get_string('changessaved'), '');
close_window(3);
@@ -279,6 +270,7 @@ if ($mform->is_cancelled()){
}
redirect($returnurl);
}
+
} else {
$nexturlparams = array(
'returnurl' => $originalreturnurl,
@@ -297,8 +289,8 @@ if ($mform->is_cancelled()){
}
redirect($nexturl);
}
-} else {
+} else {
$streditingquestion = $QTYPES[$question->qtype]->get_heading();
$PAGE->set_title($streditingquestion);
$PAGE->set_heading($COURSE->fullname);
@@ -316,7 +308,7 @@ if ($mform->is_cancelled()){
} else {
$strediting = ''.get_string("editquestions", "quiz").' -> '.$streditingquestion;
- $PAGE->navbar->add(get_string('editquestions', "quiz"), $returnurl);
+ $PAGE->navbar->add(get_string('editquestions', 'quiz'), $returnurl);
$PAGE->navbar->add($streditingquestion);
echo $OUTPUT->header();
}
diff --git a/question/type/calculated/questiontype.php b/question/type/calculated/questiontype.php
index 9e646a47aa9..847bf598d9c 100644
--- a/question/type/calculated/questiontype.php
+++ b/question/type/calculated/questiontype.php
@@ -2108,44 +2108,14 @@ class question_calculated_qtype extends default_questiontype {
return $new_question;
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
-
+ function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- $component = 'qtype_numerical';
- $filearea = 'instruction';
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
+
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
+
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_numerical', 'instruction', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/calculatedmulti/questiontype.php b/question/type/calculatedmulti/questiontype.php
index d7a4ec059d7..e4f3abffc82 100644
--- a/question/type/calculatedmulti/questiontype.php
+++ b/question/type/calculatedmulti/questiontype.php
@@ -548,48 +548,18 @@ class question_calculatedmulti_qtype extends question_calculated_qtype {
return $new_question;
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- // move files belonging to question component
- parent::move_files($question, $newcategory);
-
- // move files belonging to qtype_calculatedmulti
+ function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- $component = 'qtype_calculatedmulti';
- foreach (array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback') as $filearea) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid, true);
+
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_calculatedmulti', 'correctfeedback', $questionid);
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_calculatedmulti', 'partiallycorrectfeedback', $questionid);
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_calculatedmulti', 'incorrectfeedback', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/calculatedsimple/questiontype.php b/question/type/calculatedsimple/questiontype.php
index ea9d6cb7d7a..621bd2750ea 100644
--- a/question/type/calculatedsimple/questiontype.php
+++ b/question/type/calculatedsimple/questiontype.php
@@ -341,45 +341,15 @@ class question_calculatedsimple_qtype extends question_calculated_qtype {
return $new_question;
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
+ function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'feedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- $component = 'qtype_calculatedsimple';
- $filearea = 'feedback';
- $filearea = 'instruction';
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
+
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
+
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_calculatedsimple', 'instruction', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/edit_question_form.php b/question/type/edit_question_form.php
index c6df77c3675..3ae83d86c40 100644
--- a/question/type/edit_question_form.php
+++ b/question/type/edit_question_form.php
@@ -46,7 +46,6 @@ class question_edit_form extends moodleform {
public $contexts;
public $category;
public $categorycontext;
- public $coursefilesid;
/** @var object current context */
public $context;
@@ -64,25 +63,20 @@ class question_edit_form extends moodleform {
$this->contexts = $contexts;
- $record = $DB->get_record('question_categories', array('id'=>$question->category), 'contextid');
+ $record = $DB->get_record('question_categories', array('id' => $question->category), 'contextid');
$this->context = get_context_instance_by_id($record->contextid);
- $this->editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'context'=>$this->context);
- $this->fileoptions = array('subdir'=>true, 'maxfiles'=>-1, 'maxbytes'=>-1);
+ $this->editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'context' => $this->context);
+ $this->fileoptions = array('subdir' => true, 'maxfiles' => -1, 'maxbytes' => -1);
$this->category = $category;
$this->categorycontext = get_context_instance_by_id($category->contextid);
- //** *
- //course id or site id depending on question cat context
- $this->coursefilesid = get_filesdir_from_context(get_context_instance_by_id($category->contextid));
if (!empty($question->id)) {
- $question->id = (int)$question->id;
- //$this->instance = new
+ $question->id = (int) $question->id;
}
parent::moodleform($submiturl, null, 'post', '', null, $formeditable);
-
}
/**
@@ -104,20 +98,20 @@ class question_edit_form extends moodleform {
$mform->addElement('header', 'generalheader', get_string("general", 'form'));
if (!isset($this->question->id)){
- //adding question
+ // Adding question
$mform->addElement('questioncategory', 'category', get_string('category', 'quiz'),
array('contexts' => $this->contexts->having_cap('moodle/question:add')));
} elseif (!($this->question->formoptions->canmove || $this->question->formoptions->cansaveasnew)){
- //editing question with no permission to move from category.
+ // Editing question with no permission to move from category.
$mform->addElement('questioncategory', 'category', get_string('category', 'quiz'),
array('contexts' => array($this->categorycontext)));
} elseif ($this->question->formoptions->movecontext){
- //moving question to another context.
+ // Moving question to another context.
$mform->addElement('questioncategory', 'categorymoveto', get_string('category', 'quiz'),
array('contexts' => $this->contexts->having_cap('moodle/question:add')));
} else {
- //editing question with permission to move from category or save as new q
+ // Editing question with permission to move from category or save as new q
$currentgrp = array();
$currentgrp[0] =& $mform->createElement('questioncategory', 'category', get_string('categorycurrent', 'question'),
array('contexts' => array($this->categorycontext)));
@@ -143,7 +137,7 @@ class question_edit_form extends moodleform {
$mform->addRule('name', null, 'required', null, 'client');
$mform->addElement('editor', 'questiontext', get_string('questiontext', 'quiz'),
- array('rows' => 15, 'course' => $this->coursefilesid), $this->editoroptions);
+ array('rows' => 15), $this->editoroptions);
$mform->setType('questiontext', PARAM_RAW);
$mform->addElement('text', 'defaultgrade', get_string('defaultgrade', 'quiz'),
@@ -160,7 +154,7 @@ class question_edit_form extends moodleform {
$mform->setDefault('penalty', 0.1);
$mform->addElement('editor', 'generalfeedback', get_string('generalfeedback', 'quiz'),
- array('rows' => 10, 'course' => $this->coursefilesid), $this->editoroptions);
+ array('rows' => 10), $this->editoroptions);
$mform->setType('generalfeedback', PARAM_RAW);
$mform->addHelpButton('generalfeedback', 'generalfeedback', 'quiz');
@@ -243,15 +237,15 @@ class question_edit_form extends moodleform {
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
$mform->closeHeaderBefore('buttonar');
- if ($this->question->formoptions->movecontext){
+ if ($this->question->formoptions->movecontext) {
$mform->hardFreezeAllVisibleExcept(array('categorymoveto', 'buttonar'));
- } elseif ((!empty($this->question->id)) && (!($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew))){
+ } else if ((!empty($this->question->id)) && (!($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew))){
$mform->hardFreezeAllVisibleExcept(array('categorymoveto', 'buttonar', 'currentgrp'));
}
}
function validation($fromform, $files) {
- $errors= parent::validation($fromform, $files);
+ $errors = parent::validation($fromform, $files);
if (empty($fromform->makecopy) && isset($this->question->id)
&& ($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew)
&& empty($fromform->usecurrentcat) && !$this->question->formoptions->canmove) {
@@ -284,7 +278,7 @@ class question_edit_form extends moodleform {
$repeated[] =& $mform->createElement('text', 'answer', get_string('answer', 'quiz'), array('size' => 80));
$repeated[] =& $mform->createElement('select', 'fraction', get_string('grade'), $gradeoptions);
$repeated[] =& $mform->createElement('editor', 'feedback', get_string('feedback', 'quiz'),
- array('course' => $this->coursefilesid), $this->editoroptions);
+ array('rows' => 5), $this->editoroptions);
$repeatedoptions['answer']['type'] = PARAM_RAW;
$repeatedoptions['fraction']['default'] = 0;
$answersoption = 'answers';
diff --git a/question/type/essay/questiontype.php b/question/type/essay/questiontype.php
index 8fb9a8c871b..55dfaeb56f7 100644
--- a/question/type/essay/questiontype.php
+++ b/question/type/essay/questiontype.php
@@ -156,33 +156,9 @@ class question_essay_qtype extends default_questiontype {
return $this->save_question($question, $form, $course);
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
-
- $fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
+ function move_files($questionid, $oldcontextid, $newcontextid) {
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/match/questiontype.php b/question/type/match/questiontype.php
index 9ca99cae2fb..a8656663d71 100644
--- a/question/type/match/questiontype.php
+++ b/question/type/match/questiontype.php
@@ -492,39 +492,6 @@ class question_match_qtype extends default_questiontype {
return 1 / count($question->options->subquestions);
}
- function find_file_links($question, $courseid){
- // find links in the question_match_sub table.
- $urls = array();
- if (isset($question->options->subquestions)){
- foreach ($question->options->subquestions as $subquestion) {
- $urls += question_find_file_links_from_html($subquestion->questiontext, $courseid);
- }
-
- //set all the values of the array to the question object
- if ($urls){
- $urls = array_combine(array_keys($urls), array_fill(0, count($urls), array($question->id)));
- }
- }
- $urls = array_merge_recursive($urls, parent::find_file_links($question, $courseid));
-
- return $urls;
- }
-
- function replace_file_links($question, $fromcourseid, $tocourseid, $url, $destination){
- global $DB;
- parent::replace_file_links($question, $fromcourseid, $tocourseid, $url, $destination);
- // replace links in the question_match_sub table.
- if (isset($question->options->subquestions)){
- foreach ($question->options->subquestions as $subquestion) {
- $subquestionchanged = false;
- $subquestion->questiontext = question_replace_file_links_in_html($subquestion->questiontext, $fromcourseid, $tocourseid, $url, $destination, $subquestionchanged);
- if ($subquestionchanged){//need to update rec in db
- $DB->update_record('question_match_sub', $subquestion);
- }
- }
- }
- }
-
/**
* Runs all the code required to set up and save an essay question for testing purposes.
* Alternate DB table prefix may be used to facilitate data deletion.
@@ -544,36 +511,20 @@ class question_match_qtype extends default_questiontype {
return $this->save_question($question, $form, $course);
}
- function move_files($question, $newcategory) {
+ function move_files($questionid, $oldcontextid, $newcontextid) {
global $DB;
- // move files belonging to question component
- parent::move_files($question, $newcategory);
-
- // move files belonging to qtype_multichoice
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- // process files in sub questions
- if (!$subquestions = $DB->get_records('question_match_sub', array('question' => $question->id), 'id ASC')) {
- $subquestions = array();
- }
- $component = 'qtype_match';
- $filearea = 'subquestion';
- foreach ($subquestions as $sub) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $sub->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+
+ $subquestionids = $DB->get_records_menu('question_match_sub',
+ array('question' => $questionid), 'id', 'id,1');
+ foreach ($subquestionids as $subquestionid => $notused) {
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_match', 'subquestion', $subquestionid);
}
}
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
diff --git a/question/type/multichoice/edit_multichoice_form.php b/question/type/multichoice/edit_multichoice_form.php
index e062fc68126..ed4484c71c8 100644
--- a/question/type/multichoice/edit_multichoice_form.php
+++ b/question/type/multichoice/edit_multichoice_form.php
@@ -66,7 +66,7 @@ class question_edit_multichoice_form extends question_edit_form {
foreach (array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback') as $feedbackname) {
$mform->addElement('editor', $feedbackname, get_string($feedbackname, 'qtype_multichoice'),
- array('course' => $this->coursefilesid), $this->editoroptions);
+ array('rows' => 10), $this->editoroptions);
$mform->setType($feedbackname, PARAM_RAW);
}
diff --git a/question/type/multichoice/questiontype.php b/question/type/multichoice/questiontype.php
index ee3e506f232..88c189bd949 100644
--- a/question/type/multichoice/questiontype.php
+++ b/question/type/multichoice/questiontype.php
@@ -14,10 +14,6 @@ class question_multichoice_qtype extends default_questiontype {
return 'multichoice';
}
- function has_html_answers() {
- return true;
- }
-
function get_question_options(&$question) {
global $DB, $OUTPUT;
// Get additional information from database
@@ -489,48 +485,6 @@ class question_multichoice_qtype extends default_questiontype {
}
}
- function find_file_links($question, $courseid){
- $urls = array();
- // find links in the answers table.
- $urls += question_find_file_links_from_html($question->options->correctfeedback, $courseid);
- $urls += question_find_file_links_from_html($question->options->partiallycorrectfeedback, $courseid);
- $urls += question_find_file_links_from_html($question->options->incorrectfeedback, $courseid);
- foreach ($question->options->answers as $answer) {
- $urls += question_find_file_links_from_html($answer->answer, $courseid);
- }
- //set all the values of the array to the question id
- if ($urls){
- $urls = array_combine(array_keys($urls), array_fill(0, count($urls), array($question->id)));
- }
- $urls = array_merge_recursive($urls, parent::find_file_links($question, $courseid));
- return $urls;
- }
-
- function replace_file_links($question, $fromcourseid, $tocourseid, $url, $destination){
- global $DB;
- parent::replace_file_links($question, $fromcourseid, $tocourseid, $url, $destination);
- // replace links in the question_match_sub table.
- // We need to use a separate object, because in load_question_options, $question->options->answers
- // is changed from a comma-separated list of ids to an array, so calling $DB->update_record on
- // $question->options stores 'Array' in that column, breaking the question.
- $optionschanged = false;
- $newoptions = new stdClass;
- $newoptions->id = $question->options->id;
- $newoptions->correctfeedback = question_replace_file_links_in_html($question->options->correctfeedback, $fromcourseid, $tocourseid, $url, $destination, $optionschanged);
- $newoptions->partiallycorrectfeedback = question_replace_file_links_in_html($question->options->partiallycorrectfeedback, $fromcourseid, $tocourseid, $url, $destination, $optionschanged);
- $newoptions->incorrectfeedback = question_replace_file_links_in_html($question->options->incorrectfeedback, $fromcourseid, $tocourseid, $url, $destination, $optionschanged);
- if ($optionschanged){
- $DB->update_record('question_multichoice', $newoptions);
- }
- $answerchanged = false;
- foreach ($question->options->answers as $answer) {
- $answer->answer = question_replace_file_links_in_html($answer->answer, $fromcourseid, $tocourseid, $url, $destination, $answerchanged);
- if ($answerchanged){
- $DB->update_record('question_answers', $answer);
- }
- }
- }
-
/**
* Runs all the code required to set up and save an essay question for testing purposes.
* Alternate DB table prefix may be used to facilitate data deletion.
@@ -559,48 +513,19 @@ class question_multichoice_qtype extends default_questiontype {
return $this->save_question($question, $form, $course);
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- // move files belonging to question component
- parent::move_files($question, $newcategory);
- // move files belonging to qtype_multichoice
+ function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- $component = 'qtype_multichoice';
- foreach (array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback') as $filearea) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid, true);
+
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_multichoice', 'correctfeedback', $questionid);
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_multichoice', 'partiallycorrectfeedback', $questionid);
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_multichoice', 'incorrectfeedback', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/numerical/questiontype.php b/question/type/numerical/questiontype.php
index 52cc955774f..6edb3ed011a 100644
--- a/question/type/numerical/questiontype.php
+++ b/question/type/numerical/questiontype.php
@@ -754,7 +754,7 @@ class question_numerical_qtype extends question_shortanswer_qtype {
// The student did type a number, so check it with tolerances.
$this->get_tolerance_interval($answer);
return ($answer->min <= $response && $response <= $answer->max);
- }else { // $question->options->unitgradingtype > 0
+ } else { // $question->options->unitgradingtype > 0
/* testing with unitgradingtype $question->options->unitgradingtype > 0
* if the response is at least patially true
* if the numerical value agree in the interval
@@ -1089,10 +1089,10 @@ class question_numerical_qtype extends question_shortanswer_qtype {
}
/**
- * function used in function definition_inner()
- * of edit_..._form.php for
- * numerical, calculated, calculatedsimple
- */
+ * function used in function definition_inner()
+ * of edit_..._form.php for
+ * numerical, calculated, calculatedsimple
+ */
function add_units_options(&$mform, &$that){
// Units are graded
$mform->addElement('header', 'unithandling', get_string('unitshandling', 'qtype_numerical'));
@@ -1113,10 +1113,9 @@ class question_numerical_qtype extends question_shortanswer_qtype {
$mform->addGroup($multichoicedisplaygrp, 'multichoicedisplaygrp', get_string('studentunitanswer', 'qtype_numerical'),' OR ' , false);
$unitslefts = array('0' => get_string('rightexample', 'qtype_numerical'),'1' => get_string('leftexample', 'qtype_numerical'));
$mform->addElement('select', 'unitsleft', get_string('unitposition', 'qtype_numerical') , $unitslefts );
-
+
$mform->addElement('static', 'separator2', '
', '
');
-
-
+
$mform->addElement('editor', 'instructions', get_string('instructions', 'qtype_numerical'), null, $that->editoroptions);
$showunits1grp = array();
$mform->addElement('static', 'separator2', '
', '
');
@@ -1131,12 +1130,10 @@ class question_numerical_qtype extends question_shortanswer_qtype {
$mform->disabledIf('penaltygrp', 'unitrole','eq','0');
$mform->disabledIf('penaltygrp', 'unitrole','eq','1');
$mform->disabledIf('penaltygrp', 'unitrole','eq','2');
- $mform->disabledIf('unitsleft', 'unitrole','eq','0');
- $mform->disabledIf('multichoicedisplay','unitrole','eq','0');
- $mform->disabledIf('multichoicedisplay','unitrole','eq','1');
- $mform->disabledIf('multichoicedisplay','unitrole','eq','2');
-
-
+ $mform->disabledIf('unitsleft', 'unitrole','eq','0');
+ $mform->disabledIf('multichoicedisplay','unitrole','eq','0');
+ $mform->disabledIf('multichoicedisplay','unitrole','eq','1');
+ $mform->disabledIf('multichoicedisplay','unitrole','eq','2');
}
/**
@@ -1383,44 +1380,15 @@ class question_numerical_qtype extends question_shortanswer_qtype {
return $this->save_question($question, $form, $course);
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
+ function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- $component = 'qtype_numerical';
- $filearea = 'instruction';
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
+
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
+
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'qtype_numerical', 'instruction', $questionid);
}
function check_file_access($question, $state, $options, $contextid, $component,
diff --git a/question/type/questiontype.php b/question/type/questiontype.php
index 761a572ed5f..de46af65142 100644
--- a/question/type/questiontype.php
+++ b/question/type/questiontype.php
@@ -154,14 +154,6 @@ class default_questiontype {
return false;
}
- /**
- * @return whether the question_answers.answer field needs to have
- * restore_decode_content_links_worker called on it.
- */
- function has_html_answers() {
- return false;
- }
-
/**
* If your question type has a table that extends the question table, and
* you want the base class to automatically save, backup and restore the extra fields,
@@ -1529,93 +1521,6 @@ class default_questiontype {
return format_text($text, $textformat, $formatoptions, $cmoptions === NULL ? NULL : $cmoptions->course);
}
- /*
- * Find all course / site files linked from a question.
- *
- * Need to check for links to files in question_answers.answer and feedback
- * and in question table in generalfeedback and questiontext fields. Methods
- * on child classes will also check extra question specific fields.
- *
- * Needs to be overriden for child classes that have extra fields containing
- * html.
- *
- * @param string html the html to search
- * @param int courseid search for files for courseid course or set to siteid for
- * finding site files.
- * @return array of url, relative url is key and array with one item = question id as value
- * relative url is relative to course/site files directory root.
- */
- function find_file_links($question, $courseid){
- $urls = array();
- /// Questiontext and general feedback.
- $urls += question_find_file_links_from_html($question->questiontext, $courseid);
- $urls += question_find_file_links_from_html($question->generalfeedback, $courseid);
-
- /// Answers, if this question uses them.
- if (isset($question->options->answers)){
- foreach ($question->options->answers as $answerkey => $answer){
- /// URLs in the answers themselves, if appropriate.
- if ($this->has_html_answers()) {
- $urls += question_find_file_links_from_html($answer->answer, $courseid);
- }
- /// URLs in the answer feedback.
- $urls += question_find_file_links_from_html($answer->feedback, $courseid);
- }
- }
-
- /// Set all the values of the array to the question object
- if ($urls){
- $urls = array_combine(array_keys($urls), array_fill(0, count($urls), array($question->id)));
- }
- return $urls;
- }
- /*
- * Find all course / site files linked from a question.
- *
- * Need to check for links to files in question_answers.answer and feedback
- * and in question table in generalfeedback and questiontext fields. Methods
- * on child classes will also check extra question specific fields.
- *
- * Needs to be overriden for child classes that have extra fields containing
- * html.
- *
- * @param string html the html to search
- * @param int course search for files for courseid course or set to siteid for
- * finding site files.
- * @return array of files, file name is key and array with one item = question id as value
- */
- function replace_file_links($question, $fromcourseid, $tocourseid, $url, $destination){
- global $CFG, $DB;
- $updateqrec = false;
- /// Questiontext and general feedback.
- $question->questiontext = question_replace_file_links_in_html($question->questiontext, $fromcourseid, $tocourseid, $url, $destination, $updateqrec);
- $question->generalfeedback = question_replace_file_links_in_html($question->generalfeedback, $fromcourseid, $tocourseid, $url, $destination, $updateqrec);
-
- /// If anything has changed, update it in the database.
- if ($updateqrec){
- $DB->update_record('question', $question);
- }
-
-
- /// Answers, if this question uses them.
- if (isset($question->options->answers)){
- //answers that do not need updating have been unset
- foreach ($question->options->answers as $answer){
- $answerchanged = false;
- /// URLs in the answers themselves, if appropriate.
- if ($this->has_html_answers()) {
- $answer->answer = question_replace_file_links_in_html($answer->answer, $fromcourseid, $tocourseid, $url, $destination, $answerchanged);
- }
- /// URLs in the answer feedback.
- $answer->feedback = question_replace_file_links_in_html($answer->feedback, $fromcourseid, $tocourseid, $url, $destination, $answerchanged);
- /// If anything has changed, update it in the database.
- if ($answerchanged){
- $DB->update_record('question_answers', $answer);
- }
- }
- }
- }
-
/**
* @return the best link to pass to print_error.
* @param $cmoptions as passed in from outside.
@@ -1755,31 +1660,39 @@ class default_questiontype {
}
/**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
+ * Move all the files belonging to this question from one context to another.
+ * @param object $question the question to move.
+ * @param integer $oldcontextid the context it is moving from.
+ * @param integer $newcontextid the context it is moving to.
*/
- function move_files($question, $newcategory) {
+ public function move_files($questionid, $oldcontextid, $newcontextid) {
+ $fs = get_file_storage();
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'question', 'questiontext', $questionid);
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'question', 'generalfeedback', $questionid);
+ }
+
+ /**
+ *
+ * @param object $question the question to move.
+ * @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,
+ * as well as an 'answerfeedback' one. Default false.
+ */
+ protected function move_files_in_answers($questionid, $oldcontextid, $newcontextid, $answerstoo = false) {
global $DB;
$fs = get_file_storage();
- $component = 'question';
- // process general question files
- // Currently we have questiontext and generalfeedback areas
- foreach (array('questiontext', 'generalfeedback') as $filearea) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $question->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- if ($newcategory->contextid == $question->contextid) {
- continue;
- }
- $newfile = new stdClass();
- // only contextid changed
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- // delete old files
- $storedfile->delete();
- }
+ $answerids = $DB->get_records_menu('question_answers',
+ array('question' => $questionid), 'id', 'id,1');
+ foreach ($answerids as $answerid => $notused) {
+ if ($answerstoo) {
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'question', 'answer', $answerid);
}
+ $fs->move_area_files_to_new_context($oldcontextid,
+ $newcontextid, 'question', 'answerfeedback', $answerid);
}
}
diff --git a/question/type/shortanswer/questiontype.php b/question/type/shortanswer/questiontype.php
index 63ebbffe6b0..76eba7b21cb 100644
--- a/question/type/shortanswer/questiontype.php
+++ b/question/type/shortanswer/questiontype.php
@@ -49,33 +49,9 @@ class question_shortanswer_qtype extends default_questiontype {
return 'question';
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
-
- $fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
+ function move_files($questionid, $oldcontextid, $newcontextid) {
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
}
function save_question_options($question) {
diff --git a/question/type/truefalse/questiontype.php b/question/type/truefalse/questiontype.php
index 7663b0ee308..f4d73e3b893 100644
--- a/question/type/truefalse/questiontype.php
+++ b/question/type/truefalse/questiontype.php
@@ -257,6 +257,11 @@ class question_truefalse_qtype extends default_questiontype {
include("$CFG->dirroot/question/type/truefalse/display.html");
}
+ function move_files($questionid, $oldcontextid, $newcontextid) {
+ parent::move_files($questionid, $oldcontextid, $newcontextid);
+ $this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
+ }
+
function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
if ($component == 'question' && $filearea == 'answerfeedback') {
@@ -332,34 +337,6 @@ class question_truefalse_qtype extends default_questiontype {
return $this->save_question($question, $form, $course);
}
- /**
- * When move the category of questions, the belonging files should be moved as well
- * @param object $question, question information
- * @param object $newcategory, target category information
- */
- function move_files($question, $newcategory) {
- global $DB;
- parent::move_files($question, $newcategory);
-
- $fs = get_file_storage();
- // process files in answer
- if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
- $oldanswers = array();
- }
- $component = 'question';
- $filearea = 'answerfeedback';
- foreach ($oldanswers as $answer) {
- $files = $fs->get_area_files($question->contextid, $component, $filearea, $answer->id);
- foreach ($files as $storedfile) {
- if (!$storedfile->is_directory()) {
- $newfile = new stdClass();
- $newfile->contextid = (int)$newcategory->contextid;
- $fs->create_file_from_storedfile($newfile, $storedfile);
- $storedfile->delete();
- }
- }
- }
- }
}
//// END OF CLASS ////