";
echo "";
-
+
//This tr is slighty different. Everything becomes hidden if
//we haven't messages is the backup, to avoid confusions to users.
//If messages are in the backup file, show menu, else fixed to no and show nothing
@@ -470,48 +491,48 @@ echo (''.get_string('sourcerole').'
if ($info->backup_moodle_version < 2006092801) {
// 1.6 and below backup
-
+
/// Editting teacher
echo ('| ');
print_string('defaultcourseteacher');
echo (' | ');
-
+
// get the first teacheredit legacy
$roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM, SITEID));
$editteacher = array_shift($roles);
choose_from_menu ($siterolesarray, "defaultteacheredit", $editteacher->id, 'new role', '', '0');
echo (' | ');
-
+
/// Non-editting teacher
echo ('| ');
print_string('noneditingteacher');
echo (' | ');
-
+
// get the first teacheredit legacy
$roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM, SITEID));
$teacher = array_shift($roles);
-
+
choose_from_menu ($siterolesarray, "defaultteacher", $teacher->id, 'new role', '', '0');
echo (' | ');
-
-
+
+
/// Student
echo ('| ');
print_string('defaultcoursestudent');
echo (' | ');
-
+
// get the first teacheredit legacy
$roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM, SITEID));
$studentrole = array_shift($roles);
-
+
choose_from_menu ($siterolesarray, "defaultstudent", $studentrole->id, 'new role', '', '0');
echo (' | ');
-
+
} else {
// 1.7 and above backup
$roles = restore_read_xml_roles($xml_file);
-
+
if (!empty($roles->roles)) { // possible to have course with no roles
foreach ($siterolesarray as $siteroleid=>$siteroleshortname) {
$siteroleschoicearray[$siteroleid] = $siterolesnamearray[$siteroleid]." (". $siterolesarray[$siteroleid].")";
@@ -521,21 +542,21 @@ if ($info->backup_moodle_version < 2006092801) {
echo ('| ');
echo $role->name." (".($role->shortname).")";
echo (' | ');
-
+
// see if any short name match
$matchrole = 0;
foreach ($siterolesarray as $siteroleid=>$siteroleshortname) {
if ($siteroleshortname == $role->shortname) {
$matchrole = $siteroleid;
- break;
- }
+ break;
+ }
}
-
+
choose_from_menu ($siteroleschoicearray, "roles_".$roleid, $matchrole, 'new role', '', '0');
- echo (' | ');
+ echo (' | ');
}
}
-
+
} // end else
echo (''); // end of role mappings table
diff --git a/backup/restorelib.php b/backup/restorelib.php
index af85a96f903..6ab234e0891 100644
--- a/backup/restorelib.php
+++ b/backup/restorelib.php
@@ -451,6 +451,14 @@
$tab[$elem][1] = get_string("no");
}
$elem++;
+ //site Files info
+ $tab[$elem][0] = "".get_string("sitefiles").":";
+ if ($info->backup_site_files == "true") {
+ $tab[$elem][1] = get_string("yes");
+ } else {
+ $tab[$elem][1] = get_string("no");
+ }
+ $elem++;
//Messages info (only showed if present)
if ($info->backup_messages == 'true') {
$tab[$elem][0] = "".get_string('messages','message').":";
@@ -671,43 +679,7 @@
return $status;
}
- /**
- * Returns the best question category (id) found to restore one
- * question category from a backup file. Works by stamp (since Moodle 1.1)
- * or by name (for older versions).
- *
- * @param object $cat the question_categories record to be searched
- * @param integer $courseid the course where we are restoring
- * @return integer the id of a existing question_category or 0 (not found)
- */
- function restore_get_best_question_category($cat, $courseid) {
- $found = 0;
-
- //Decide how to work (by stamp or name)
- if ($cat->stamp) {
- $searchfield = 'stamp';
- $searchvalue = $cat->stamp;
- } else {
- $searchfield = 'name';
- $searchvalue = $cat->name;
- }
-
- //First shot. Try to get the category from the course being restored
- if ($fcat = get_record('question_categories','course',$courseid,$searchfield,$searchvalue)) {
- $found = $fcat->id;
- //Second shot. Try to obtain any concordant category and check its publish status and editing rights
- } else if ($fcats = get_records('question_categories', $searchfield, $searchvalue, 'id', 'id, publish, course')) {
- foreach ($fcats as $fcat) {
- if ($fcat->publish == 1 && has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE, $fcat->course))) {
- $found = $fcat->id;
- break;
- }
- }
- }
-
- return $found;
- }
//This function creates all the block stuff when restoring courses
//It calls selectively to restore_create_block_instances() for 1.5
@@ -1353,7 +1325,7 @@
//$GLOBALS['traverse_array']=""; //Debug
//Now build the GRADE_PREFERENCES record structure
if ($info['GRADE_OUTCOME']['#']['COURSEID']['0']['#']) {
- $dbrec->courseid = $restore->course_id;
+ $dbrec->courseid = $restore->course_id;
} else {
$dbrec->courseid = NULL;
}
@@ -1369,22 +1341,22 @@
$dbrec->usermodified = $modifier->new_id;
// Structure is equal to db, insert record
- // If the shortname doesn't exist
-
+ // If the shortname doesn't exist
+
if (empty($info['GRADE_OUTCOME']['#']['COURSEID']['0']['#'])) {
- $prerec = get_record_sql("SELECT * FROM {$CFG->prefix}grade_outcomes
+ $prerec = get_record_sql("SELECT * FROM {$CFG->prefix}grade_outcomes
WHERE courseid IS NULL
AND shortname = '$dbrec->shortname'");
} else {
$prerec = get_record('grade_outcomes','courseid',$restore->course_id,'shortname',$dbrec->shortname);
}
-
+
if (!$prerec) {
$newid = insert_record('grade_outcomes',$dbrec);
} else {
- $newid = $prerec->id;
+ $newid = $prerec->id;
}
-
+
if ($newid) {
backup_putid($restore->backup_unique_code,"grade_outcomes", $rec->old_id, $newid);
}
@@ -1431,7 +1403,7 @@
//$GLOBALS['traverse_array']=""; //Debug
$oldoutcomesid = backup_todb($info['GRADE_OUTCOMES_COURSE']['#']['OUTCOMEID']['0']['#']);
- $newoutcome = backup_getid($restore->backup_unique_code,"grade_outcomes",$oldoutcomesid);
+ $newoutcome = backup_getid($restore->backup_unique_code,"grade_outcomes",$oldoutcomesid);
unset($dbrec);
$dbrec->courseid = $restore->course_id;
$dbrec->outcomeid = $newoutcome->new_id;
@@ -1526,11 +1498,11 @@
if ($restoreall) {
// TODO any special code needed here to restore course item without duplicating it?
// find the course category with depth 1, and course id = current course id
- // this would have been already restored
-
+ // this would have been already restored
+
$cat = get_record('grade_categories', 'depth', 1, 'courseid', $restore->course_id);
$dbrec->iteminstance = $cat->id;
-
+
} else {
continue;
}
@@ -1550,8 +1522,8 @@
}
/// needs to be restored first
- $dbrec->outcomeid = backup_getid($restore->backup_unique_code,"grade_outcomes",backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']));
-
+ $dbrec->outcomeid = backup_getid($restore->backup_unique_code,"grade_outcomes",backup_todb($info['GRADE_ITEM']['#']['OUTCOMEID']['0']['#']));
+
$dbrec->gradepass = backup_todb($info['GRADE_ITEM']['#']['GRADEPASS']['0']['#']);
$dbrec->multfactor = backup_todb($info['GRADE_ITEM']['#']['MULTFACTOR']['0']['#']);
$dbrec->plusfactor = backup_todb($info['GRADE_ITEM']['#']['PLUSFACTOR']['0']['#']);
@@ -1625,6 +1597,7 @@
}
+
/// processing grade_grades_text
if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES_TEXT']['0']['#']) && ($texts = $info['GRADE_ITEM']['#']['GRADE_GRADES_TEXT']['0']['#']['GRADE_TEXT'])) {
//Iterate over items
@@ -1634,7 +1607,7 @@
//print_object ($GLOBALS['traverse_array']); //Debug
//$GLOBALS['traverse_array']=""; //Debug
$grade = backup_getid($restore->backup_unique_code,"grade_grades", backup_todb($ite_info['#']['GRADEID']['0']['#']));
-
+
$text->gradeid = $grade->new_id;
$text->information = backup_todb($ite_info['#']['INFORMATION']['0']['#']);
$text->informationformat = backup_todb($ite_info['#']['INFORMATIONFORMAT']['0']['#']);
@@ -1687,35 +1660,35 @@
$info = $data->info;
//traverse_xmlize($info); //Debug
//print_object ($GLOBALS['traverse_array']); //Debug
- //$GLOBALS['traverse_array']=""; //Debug
-
+ //$GLOBALS['traverse_array']=""; //Debug
+
$oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['OLDID']['0']['#']));
if (empty($oldobj->new_id)) {
// if the old object is not being restored, can't restoring its history
$counter++;
- continue;
+ continue;
}
- $dbrec->oldid = $oldobj->new_id;
- $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
+ $dbrec->oldid = $oldobj->new_id;
+ $dbrec->action = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['ACTION']['0']['#']);
$dbrec->source = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['SOURCE']['0']['#']);
$dbrec->timemodified = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
-
+
// loggeduser might not be restored, e.g. admin
if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
$dbrec->loggeduser = $oldobj->new_id;
- }
-
+ }
+
// this item might not have a parent at all, do not skip it if no parent is specified
if (backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#'])) {
- $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
+ $oldobj = backup_getid($restore->backup_unique_code,"grade_categories", backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PARENT']['0']['#']));
if (empty($oldobj->new_id)) {
// if the parent category not restored
$counter++;
- continue;
- }
- }
+ continue;
+ }
+ }
$dbrec->parent = $oldobj->new_id;
- $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
+ $dbrec->depth = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DEPTH']['0']['#']);
// path needs to be rebuilt
if ($path = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['PATH']['0']['#'])) {
// to preserve the path and make it work, we need to replace the categories one by one
@@ -1735,7 +1708,7 @@
$dbrec->fullname = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['FULLNAME']['0']['#']);
$dbrec->aggregation = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['AGGRETGATION']['0']['#']);
$dbrec->keephigh = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['KEEPHIGH']['0']['#']);
- $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
+ $dbrec->droplow = backup_todb($info['GRADE_CATEGORIES_HISTORY']['#']['DROPLOW']['0']['#']);
$dbrec->courseid = $restore->course_id;
insert_record('grade_categories_history', $dbrec);
unset($dbrec);
@@ -1786,7 +1759,7 @@
if (empty($oldobj->new_id)) {
// if the old object is not being restored, can't restoring its history
$counter++;
- continue;
+ continue;
}
$dbrec->oldid = $oldobj->new_id;
$dbrec->action = backup_todb($info['GRADE_GRADES_HISTORY']['#']['ACTION']['0']['#']);
@@ -1816,7 +1789,7 @@
$dbrec->exported = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXPORTED']['0']['#']);
$dbrec->overridden = backup_todb($info['GRADE_GRADES_HISTORY']['#']['OVERRIDDEN']['0']['#']);
$dbrec->excluded = backup_todb($info['GRADE_GRADES_HISTORY']['#']['EXCLUDED']['0']['#']);
-
+
insert_record('grade_grades_history', $dbrec);
unset($dbrec);
@@ -1863,12 +1836,12 @@
//traverse_xmlize($info); //Debug
//print_object ($GLOBALS['traverse_array']); //Debug
//$GLOBALS['traverse_array']=""; //Debug
-
+
$oldobj = backup_getid($restore->backup_unique_code,"grade_grades_text", backup_todb($info['GRADE_TEXT_HISTORY']['#']['OLDID']['0']['#']));
if (empty($oldobj->new_id)) {
// if the old object is not being restored, can't restoring its history
$counter++;
- continue;
+ continue;
}
$dbrec->oldid = $oldobj->new_id;
$dbrec->action = backup_todb($info['GRADE_TEXT_HISTORY']['#']['ACTION']['0']['#']);
@@ -1876,20 +1849,20 @@
$dbrec->timemodified = backup_todb($info['GRADE_TEXT_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_TEXT_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
$dbrec->loggeduser = $oldobj->new_id;
- }
- $oldobj = backup_getid($restore->backup_unique_code,"grade_grades", backup_todb($info['GRADE_TEXT_HISTORY']['#']['GRADEID']['0']['#']));
- $dbrec->gradeid = $oldobj->new_id;
+ }
+ $oldobj = backup_getid($restore->backup_unique_code,"grade_grades", backup_todb($info['GRADE_TEXT_HISTORY']['#']['GRADEID']['0']['#']));
+ $dbrec->gradeid = $oldobj->new_id;
if (empty($dbrec->gradeid)) {
$counter++;
- continue; // grade not being restore, possibly because grade item is not restored
+ continue; // grade not being restore, possibly because grade item is not restored
}
- $oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_TEXT_HISTORY']['#']['USERID']['0']['#']));
+ $oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_TEXT_HISTORY']['#']['USERID']['0']['#']));
$dbrec->userid = $oldobj->new_id;
$dbrec->information = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATION']['0']['#']);
$dbrec->informationformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['INFORMATIONFORMAT']['0']['#']);
$dbrec->feedback = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACK']['0']['#']);
- $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
- if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_TEXT_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
+ $dbrec->feedbackformat = backup_todb($info['GRADE_TEXT_HISTORY']['#']['FEEDBACKFORMAT']['0']['#']);
+ if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_TEXT_HISTORY']['#']['USERMODIFIED']['0']['#']))) {
$dbrec->usermodified = $oldobj->new_id;
}
@@ -1939,11 +1912,11 @@
//$GLOBALS['traverse_array']=""; //Debug
- $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
+ $oldobj = backup_getid($restore->backup_unique_code,"grade_items", backup_todb($info['GRADE_ITEM_HISTORY']['#']['OLDID']['0']['#']));
if (empty($oldobj->new_id)) {
// if the old object is not being restored, can't restoring its history
$counter++;
- continue;
+ continue;
}
$dbrec->oldid = $oldobj->new_id;
$dbrec->action = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ACTION']['0']['#']);
@@ -1951,18 +1924,18 @@
$dbrec->timemodified = backup_todb($info['GRADE_ITEM_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
if ($oldobj = backup_getid($restore->backup_unique_code,"user", backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOGGEDUSER']['0']['#']))) {
$dbrec->loggeduser = $oldobj->new_id;
- }
+ }
$oldobj = backup_getid($restore->backup_unique_code,'grade_categories',backup_todb($info['GRADE_ITEM_HISTORY']['#']['CATEGORYID']['0']['#']));
- $oldobj->categoryid = $category->new_id;
+ $oldobj->categoryid = $category->new_id;
if (empty($oldobj->categoryid)) {
$counter++;
- continue; // category not restored
+ continue; // category not restored
}
-
+
$dbrec->itemname= backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNAME']['0']['#']);
$dbrec->itemtype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMTYPE']['0']['#']);
$dbrec->itemmodule = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMMODULE']['0']['#']);
-
+
// code from grade_items restore
$iteminstance = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINSTANCE']['0']['#']);
// do not restore if this grade_item is a mod, and
@@ -1996,11 +1969,11 @@
if ($restoreall) {
// TODO any special code needed here to restore course item without duplicating it?
// find the course category with depth 1, and course id = current course id
- // this would have been already restored
-
+ // this would have been already restored
+
$cat = get_record('grade_categories', 'depth', 1, 'courseid', $restore->course_id);
$dbrec->iteminstance = $cat->id;
-
+
} else {
$counter++;
continue;
@@ -2008,7 +1981,7 @@
}
$dbrec->itemnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMNUMBER']['0']['#']);
- $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
+ $dbrec->iteminfo = backup_todb($info['GRADE_ITEM_HISTORY']['#']['ITEMINFO']['0']['#']);
$dbrec->idnumber = backup_todb($info['GRADE_ITEM_HISTORY']['#']['IDNUMBER']['0']['#']);
$dbrec->calculation = backup_todb($info['GRADE_ITEM_HISTORY']['#']['CALCULATION']['0']['#']);
$dbrec->gradetype = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADETYPE']['0']['#']);
@@ -2024,14 +1997,14 @@
}
$dbrec->gradepass = backup_todb($info['GRADE_ITEM_HISTORY']['#']['GRADEPASS']['0']['#']);
$dbrec->multfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['MULTFACTOR']['0']['#']);
- $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
+ $dbrec->plusfactor = backup_todb($info['GRADE_ITEM_HISTORY']['#']['PLUSFACTOR']['0']['#']);
$dbrec->aggregationcoef = backup_todb($info['GRADE_ITEM_HISTORY']['#']['AGGREGATIONCOEF']['0']['#']);
$dbrec->sortorder = backup_todb($info['GRADE_ITEM_HISTORY']['#']['SORTORDER']['0']['#']);
$dbrec->hidden = backup_todb($info['GRADE_ITEM_HISTORY']['#']['HIDDEN']['0']['#']);
$dbrec->locked = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKED']['0']['#']);
$dbrec->locktime = backup_todb($info['GRADE_ITEM_HISTORY']['#']['LOCKTIME']['0']['#']);
- $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
-
+ $dbrec->needsupdate = backup_todb($info['GRADE_ITEM_HISTORY']['#']['NEEDSUPDATE']['0']['#']);
+
insert_record('grade_items_history', $dbrec);
unset($dbrec);
@@ -2081,9 +2054,9 @@
if (empty($oldobj->new_id)) {
// if the old object is not being restored, can't restoring its history
$counter++;
- continue;
+ continue;
}
- $dbrec->oldid = $oldobj->new_id;
+ $dbrec->oldid = $oldobj->new_id;
$dbrec->action = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['ACTION']['0']['#']);
$dbrec->source = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SOURCE']['0']['#']);
$dbrec->timemodified = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['TIMEMODIFIED']['0']['#']);
@@ -2091,11 +2064,11 @@
$dbrec->loggeduser = $oldobj->new_id;
}
$dbrec->shortname = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SHORTNAME']['0']['#']);
- $dbrec->fullname= backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
+ $dbrec->fullname= backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['FULLNAME']['0']['#']);
$oldobj = backup_getid($restore->backup_unique_code,"scale", backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['SCALEID']['0']['#']));
$dbrec->scaleid = $oldobj->new_id;
$dbrec->description = backup_todb($info['GRADE_OUTCOME_HISTORY']['#']['DESCRIPTION']['0']['#']);
-
+
insert_record('grade_outcomes_history', $dbrec);
unset($dbrec);
@@ -2676,34 +2649,7 @@
//categories/questions
if ($info) {
if ($info !== true) {
- //Iterate over each category
- foreach ($info as $category) {
- //Skip empty categories (some backups can contain them)
- if (!empty($category->id)) {
- $status = restore_question_categories($category,$restore);
- }
- }
-
- //Now we have to recode the parent field of each restored category
- $categories = get_records_sql("SELECT old_id, new_id
- FROM {$CFG->prefix}backup_ids
- WHERE backup_code = $restore->backup_unique_code AND
- table_name = 'question_categories'");
- if ($categories) {
- foreach ($categories as $category) {
- $restoredcategory = get_record('question_categories','id',$category->new_id);
- $restoredcategory = addslashes_object($restoredcategory);
- if ($restoredcategory->parent != 0) {
- $idcat = backup_getid($restore->backup_unique_code,'question_categories',$restoredcategory->parent);
- if ($idcat->new_id) {
- $restoredcategory->parent = $idcat->new_id;
- } else {
- $restoredcategory->parent = 0;
- }
- update_record('question_categories', $restoredcategory);
- }
- }
- }
+ $status = $status && restore_question_categories($info, $restore);
}
} else {
$status = false;
@@ -2763,13 +2709,13 @@
} else {
$course_to_search = $restore->course_id;
}
-
+
// scale is not course unique, use get_record_sql to suppress warning
-
+
$sca_db = get_record_sql("SELECT * FROM {$CFG->prefix}scale
WHERE scale = '$sca->scale'
- AND courseid = $course_to_search", true);
-
+ AND courseid = $course_to_search", true);
+
//If it doesn't exist, create
if (!$sca_db) {
$create_scale = true;
@@ -3413,6 +3359,59 @@
}
}
+ //This function restores the site files from the temp (site_files) directory to the
+ //dataroot/SITEID directory
+ function restore_site_files($restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ $counter = 0;
+
+ //First, we check to "course_id" exists and create is as necessary
+ //in CFG->dataroot
+ $dest_dir = $CFG->dataroot."/".SITEID;
+ $status = check_dir_exists($dest_dir,true);
+
+ //Now, we iterate over "site_files" files to check if that file/dir must be
+ //copied to the "dest_dir" dir.
+ $rootdir = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/site_files";
+ //Check if directory exists
+ if (is_dir($rootdir)) {
+ $list = list_directories_and_files ($rootdir);
+ if ($list) {
+ //Iterate
+ $counter = 0;
+ foreach ($list as $dir) {
+ //Copy the dir to its new location
+ //Only if destination file/dir doesn exists
+ if (!file_exists($dest_dir."/".$dir)) {
+ $status = backup_copy_file($rootdir."/".$dir,
+ $dest_dir."/".$dir,true);
+ $counter ++;
+ }
+ //Do some output
+ if ($counter % 2 == 0) {
+ if (!defined('RESTORE_SILENTLY')) {
+ echo ".";
+ if ($counter % 40 == 0) {
+ echo " ";
+ }
+ }
+ backup_flush(300);
+ }
+ }
+ }
+ }
+ //If status is ok and whe have dirs created, returns counter to inform
+ if ($status and $counter) {
+ return $counter;
+ } else {
+ return $status;
+ }
+ }
+
//This function creates all the structures for every module in backup file
//Depending what has been selected.
@@ -4041,7 +4040,7 @@
//If we are under a GRADE_PREFERENCE, GRADE_LETTER or GRADE_CATEGORY tag under a GRADEBOOK zone, accumule it
if (isset($this->tree[5]) and isset($this->tree[3])) {
if (($this->tree[5] == "GRADE_ITEM" || $this->tree[5] == "GRADE_CATEGORY" || $this->tree[5] == "GRADE_OUTCOME" || $this->tree[5] == "GRADE_OUTCOMES_COURSE" || $this->tree[5] == "GRADE_CATEGORIES_HISTORY" || $this->tree[5] == "GRADE_GRADES_HISTORY" || $this->tree[5] == "GRADE_TEXT_HISTORY" || $this->tree[5] == "GRADE_ITEM_HISTORY" || $this->tree[5] == "GRADE_OUTCOME_HISTORY") && ($this->tree[3] == "GRADEBOOK")) {
-
+
if (!isset($this->temp)) {
$this->temp = "";
}
@@ -4344,6 +4343,9 @@
case "COURSEFILES":
$this->info->backup_course_files = $this->getContents();
break;
+ case "SITEFILES":
+ $this->info->backup_site_files = $this->getContents();
+ break;
case "MESSAGES":
$this->info->backup_messages = $this->getContents();
break;
@@ -5209,7 +5211,7 @@
//Reset temp
unset($this->temp);
}
-
+
//If we've finished a grade_outcomes_course, xmlize it an save to db
if (($this->level == 5) and ($tagName == "GRADE_OUTCOMES_COURSE")) {
//Prepend XML standard header to info gathered
@@ -5232,8 +5234,8 @@
$this->info = $this->counter;
//Reset temp
unset($this->temp);
- }
-
+ }
+
if (($this->level == 5) and ($tagName == "GRADE_CATEGORIES_HISTORY")) {
//Prepend XML standard header to info gathered
$xml_data = "\n".$this->temp;
@@ -5258,7 +5260,7 @@
unset($this->temp);
}
-
+
if (($this->level == 5) and ($tagName == "GRADE_GRADES_HISTORY")) {
//Prepend XML standard header to info gathered
$xml_data = "\n".$this->temp;
@@ -5282,8 +5284,8 @@
//Reset temp
unset($this->temp);
- }
-
+ }
+
if (($this->level == 5) and ($tagName == "GRADE_TEXT_HISTORY")) {
//Prepend XML standard header to info gathered
$xml_data = "\n".$this->temp;
@@ -5306,8 +5308,8 @@
//Reset temp
unset($this->temp);
- }
-
+ }
+
if (($this->level == 5) and ($tagName == "GRADE_ITEM_HISTORY")) {
//Prepend XML standard header to info gathered
$xml_data = "\n".$this->temp;
@@ -5331,8 +5333,8 @@
//Reset temp
unset($this->temp);
- }
-
+ }
+
if (($this->level == 5) and ($tagName == "GRADE_OUTCOME_HISTORY")) {
//Prepend XML standard header to info gathered
$xml_data = "\n".$this->temp;
@@ -6501,6 +6503,7 @@
$restore->backup_unique_code=$backup_unique_code;
$restore->users = 2; // yuk
$restore->course_files = $SESSION->restore->restore_course_files;
+ $restore->site_files = $SESSION->restore->restore_site_files;
if ($allmods = get_records("modules")) {
foreach ($allmods as $mod) {
$modname = $mod->name;
@@ -6806,7 +6809,7 @@
//Now create categories and questions as needed
- if ($status and ($restore->mods['quiz']->restore)) {
+ if ($status) {
include_once("$CFG->dirroot/question/restorelib.php");
if (!defined('RESTORE_SILENTLY')) {
echo "".get_string("creatingcategoriesandquestions");
@@ -6879,6 +6882,34 @@
}
}
+
+ //Now create site files as needed
+ if ($status and ($restore->site_files)) {
+ if (!defined('RESTORE_SILENTLY')) {
+ echo "".get_string('copyingsitefiles');
+ }
+ if (!$status = restore_site_files($restore)) {
+ if (empty($status)) {
+ notify("Could not restore site files!");
+ } else {
+ $errorstr = "Could not restore site files!";
+ return false;
+ }
+ }
+ //If all is ok (and we have a counter)
+ if ($status and ($status !== true)) {
+ //Inform about user dirs created from backup
+ if (!defined('RESTORE_SILENTLY')) {
+ echo "";
+ echo "- ".get_string("filesfolders").": ".$status.'
';
+ echo " ";
+ }
+ }
+ if (!defined('RESTORE_SILENTLY')) {
+ echo "";
+ }
+ }
+
//Now create messages as needed
if ($status and ($restore->messages)) {
if (!defined('RESTORE_SILENTLY')) {
@@ -7577,7 +7608,7 @@
}
$newcontext = get_context_instance($contextlevel, $oldinstance->new_id);
- $override->contextid = $newcontext->id; // new context id
+ $override->contextid = $newcontext->id; // new context id
// use assign capability instead so we can add context to context_rel
assign_capability($override->capability, $override->permission, $override->roleid, $override->contextid);
}
diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php
index 822fa1da484..4686d83f5be 100644
--- a/lang/en_utf8/admin.php
+++ b/lang/en_utf8/admin.php
@@ -502,7 +502,12 @@ $string['profilevisible'] = 'Who is this field visible to?';
$string['protectusernames'] = 'Protect usernames';
$string['proxyhost'] = 'Proxy host';
$string['proxyport'] = 'Proxy port';
+$string['qtyperqpwillberemoved'] = 'During the upgrade, the RQP question type will be removed. You were not using this question type, so you should not experience any problems.';
+$string['qtyperqpwillberemovedanyway'] = 'During the upgrade, the RQP question type will be removed. You have some RQP questions in your database, and these will stop working unless you reinstall the code from http://moodle.org/mod/data/view.php?d=13&rid=797 before continuing with the upgrade.';
$string['quarantinedir'] = 'Quarantine directory';
+$string['question'] = 'Question';
+$string['questioncwqpfscheck'] = 'One or more \'random\' questions in a quiz are set up to select questions from a mixture of shared and unshared question categories. There is a more detailled report reporturl\">here and see Moodle Docs page docsurl\">here.';
+$string['questioncwqpfsok'] = 'Good. There are no \'random\' questions in your quizzes that are set up to select questions from a mixture of shared and unshared question categories.';
$string['rcache'] = 'Record cache';
$string['rcachettl'] = 'Record cache TTL';
$string['releasenoteslink'] = 'For information about this version of Moodle, please see the online Release Notes';
@@ -521,8 +526,6 @@ $string['riskspamshort'] = 'Spam risk';
$string['riskxss'] = 'Users could add files and texts that allow cross-site scripting (XSS)';
$string['riskxssshort'] = 'XSS risk';
$string['runclamavonupload'] = 'Use clam AV on uploaded files';
-$string['qtyperqpwillberemoved'] = 'During the upgrade, the RQP question type will be removed. You were not using this question type, so you should not experience any problems.';
-$string['qtyperqpwillberemovedanyway'] = 'During the upgrade, the RQP question type will be removed. You have some RQP questions in your database, and these will stop working unless you reinstall the code from http://moodle.org/mod/data/view.php?d=13&rid=797 before continuing with the upgrade.';
$string['savechanges'] = 'Save Changes';
$string['search'] = 'Search';
$string['searchresults'] = 'Search Results';
diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php
index 9cedba1fe56..28acde923db 100644
--- a/lang/en_utf8/moodle.php
+++ b/lang/en_utf8/moodle.php
@@ -159,6 +159,7 @@ $string['backupnonisowarning'] = 'Warning: this backup is from a non-Unicode ver
$string['backuporiginalname'] = 'Backup Name';
$string['backupsavetohelp'] = 'Full path to the directory where you want to save the backup files (leave blank to save in its course default dir)';
$string['backupschedulehelp'] = 'Choose which days of the week to perform automated backups.';
+$string['backupsitefileshelp'] = 'If enabled then site files used in courses will be included in automated backups';
$string['backuptakealook'] = 'Please take a look at your backup logs in:
$a';
$string['backupuserfileshelp'] = 'Choose whether user files (eg profile images) should be included in automated backups';
@@ -239,6 +240,7 @@ $string['cookiesnotenabled'] = 'Unfortunately, cookies are currently not enabled
$string['copy'] = 'copy';
$string['copyasnoun'] = 'copy';
$string['copyingcoursefiles'] = 'Copying course files';
+$string['copyingsitefiles'] = 'Copying site files used in course';
$string['copyinguserfiles'] = 'Copying user files';
$string['copyingzipfile'] = 'Copying zip file';
$string['copyrightnotice'] = 'Copyright notice';
@@ -508,7 +510,7 @@ $string['emailpasswordchangeinfodisabled'] = 'Hi $a->firstname,
Someone (probably you) has requested a new password for your
account on \'$a->sitename\'.
-Unfortunately your account on this site is disabled and can not be reset,
+Unfortunately your account on this site is disabled and can not be reset,
please contact the site administrator,
$a->admin';
$string['emailpasswordchangeinfofail'] = 'Hi $a->firstname,
@@ -516,7 +518,7 @@ $string['emailpasswordchangeinfofail'] = 'Hi $a->firstname,
Someone (probably you) has requested a new password for your
account on \'$a->sitename\'.
-Unfortunately passwords can not be reset on this site,
+Unfortunately passwords can not be reset on this site,
please contact the site administrator,
$a->admin';
$string['emailpasswordchangeinfosubject'] = '$a: Change password information';
@@ -775,6 +777,7 @@ $string['includemodules'] = 'Include Modules';
$string['includemoduleuserdata'] = 'Include module user data';
$string['includeneededusers'] = 'Include Needed Users';
$string['includenoneusers'] = 'Include No Users';
+$string['includesitefiles'] = 'Include Site Files Used in This Course';
$string['includeuserfiles'] = 'Include User Files';
$string['info'] = 'Information';
$string['institution'] = 'Institution';
@@ -1299,6 +1302,7 @@ $string['site'] = 'Site';
$string['sitedefault'] = 'Site Default';
$string['siteerrors'] = 'Site errors';
$string['sitefiles'] = 'Site files';
+$string['sitefilesused'] = 'Site files used in this course';
$string['sitelogs'] = 'Site logs';
$string['sitenews'] = 'Site news';
$string['sitepartlist'] = 'You do not have the required permissions to view the participants list';
diff --git a/lang/en_utf8/qtype_multichoice.php b/lang/en_utf8/qtype_multichoice.php
index 8cecea59f5e..809065474b3 100644
--- a/lang/en_utf8/qtype_multichoice.php
+++ b/lang/en_utf8/qtype_multichoice.php
@@ -1,6 +1,7 @@
$a->user on $a->time';
$string['categorydoesnotexist'] = 'This category does not exist';
+$string['categorycurrent'] = 'Current Category';
+$string['categorycurrentuse'] = 'Use This Category';
+$string['categorymoveto'] = 'Save in Category';
+$string['changepublishstatuscat'] = 'caturl\">Category \"$a->name\" in course \"$a->coursename\" will have it\'s sharing status changed from $a->changefrom to $a->changeto.';
+$string['cwrqpfs'] = 'Random questions selecting questions from sub categories.';
+$string['cwrqpfsinfo'] = 'During the upgrade to Moodle 1.9 we will seperate question categories into
+different contexts. Some question categories and questions on your site will have to have their sharing
+status changed. This is necessary in the rare case that one or more \'random\' questions in a quiz are set up to select from a mixture of
+shared and unshared categories (as is the case on this site). This happens when a \'random\' question is set to select
+from subcategories and one or more subcategories have a different sharing status to the parent category in which
+the random question is created.
+The following question categories, from which \'random\' questions in parent categories select questions from, will have their sharing status changed to the same sharing status as the category with the \'random\' question in on upgrading to Moodle 1.9. The following categories will have their sharing status changed. Questions which are affected will continue to work in all existing quizzes until you remove them from these quizzes.';
+$string['cwrqpfsnoprob'] = 'No question categories in your site are affected by the \'Random questions selecting questions from sub categories\' issue.';
+$string['copy']= 'Copy from $a and change links.';
+$string['created'] = 'Created';
+$string['createdmodifiedheader'] = 'Created / Modified';
+$string['defaultfor'] = 'Default for $a';
+$string['defaultinfofor'] = 'The default category for questions shared in context \'$a\'.';
+$string['donothing']= 'Don\'t copy or move files or change links.';
+$string['editingcategory'] = 'Editing a category';
$string['editingquestion'] = 'Editing a question';
-$string['missingimportantcode'] = 'This question type is missing important code: $a.';
-$string['notenoughdatatoeditaquestion'] = 'Neither a question id, nor a category id and question type, was specified.';
-$string['questionbank'] = 'Question bank';
-$string['questiondoesnotexist'] = 'This question does not exist';
-$string['unknownquestiontype'] = 'Unknown question type: $a.';
+$string['erroraccessingcontext'] = 'Cannot access context';
+$string['errorfilecannotbecopied'] = 'Error cannot copy file $a.';
+$string['errorfilecannotbemoved'] = 'Error cannot move file $a.';
+$string['errorfileschanged'] = 'Error files linked to from questions have changed since form was displayed.';
+$string['exportcategory'] = 'Export category';
+$string['filesareasite']= 'the site files area';
+$string['filesareacourse']= 'the course files area';
+$string['filestomove']= 'Move / copy files to $a?';
$string['fractionsnomax'] = 'One of the answers should have a score of 100%% so it is possible to get full marks for this question.';
+$string['getcategoryfromfile'] = 'Get category from file';
+$string['getcontextfromfile'] = 'Get context from file';
+$string['ignorebroken'] = 'Ignore broken links';
+$string['linkedfiledoesntexist'] = 'Linked file $a doesn\'t exist';
$string['makechildof'] = "Make Child of '\$a'";
$string['maketoplevelitem'] = 'Move to top level';
+$string['missingimportantcode'] = 'This question type is missing important code: $a.';
+$string['modified'] = 'Modified';
+$string['move']= 'Move from $a and change links.';
+$string['movecategory']= 'Move Category';
+$string['movelinksonly']= 'Just change where links point to, do not move or copy files.';
+$string['moveqtoanothercontext']= 'Move question to another context.';
+$string['moveq']= 'Move question(s)';
+$string['movingcategory']= 'Moving Category';
+$string['movingcategoryandfiles']= 'Are you sure you want to move category {$a->name} and all child categories to context for \"{$a->contextto}\"? We have detected {$a->urlcount} files linked from questions in {$a->fromareaname}, would you like to copy or move these to {$a->toareaname}?';
+$string['movingcategorynofiles']= 'Are you sure you want to move category \"{$a->name}\" and all child categories to context for \"{$a->contextto}\"?';
+$string['movingquestions'] = 'Moving Questions and Any Files';
+$string['movingquestionsandfiles']= 'Are you sure you want to move question(s) {$a->questions} to context for \"{$a->tocontext}\"? We have detected {$a->urlcount} files linked from these question(s) in {$a->fromareaname}, would you like to copy or move these to {$a->toareaname}?';
+$string['movingquestionsnofiles']= 'Are you sure you want to move question(s) {$a->questions} to context for \"{$a->tocontext}\"? There are no files linked from these question(s) in {$a->fromareaname}.';
+$string['needtochoosecat'] = 'You need to choose a category to move this question to or press \'cancel\'.';
+$string['nopermissionadd'] = 'You don\'t have permission to add questions here.';
+$string['noprobs'] = 'No problems found in your question database.';
+$string['notenoughdatatoeditaquestion'] = 'Neither a question id, nor a category id and question type, was specified.';
+$string['notenoughdatatomovequestions'] = 'You need to provide the question ids of questions you want to move.';
+$string['permissionedit'] = 'Edit this question';
+$string['permissionmove'] = 'Move this question';
+$string['permissionsaveasnew'] = 'Save this as a new question';
+$string['permissionto'] = 'You have permission to :';
+$string['published'] = 'published';
+$string['questionaffected'] = 'qurl\">Question \"$a->name\" ($a->qtype) is in this question category but is also being used in qurl\">quiz \"$a->quizname\" in another course \"$a->coursename\".';
+$string['questionbank'] = 'Question bank';
+$string['questioncatsfor'] = 'Question Categories for \'$a\'';
+$string['questiondoesnotexist'] = 'This question does not exist';
+$string['questionuse'] = 'Use question in this activity';
+$string['shareincontext'] = 'Share in context for $a';
+$string['tofilecategory'] = 'Write category to file';
+$string['tofilecontext'] = 'Write context to file';
+$string['unknown'] = 'Unknown';
+$string['unknownquestiontype'] = 'Unknown question type: $a.';
+$string['unpublished'] = 'unpublished';
?>
diff --git a/lang/en_utf8/quiz.php b/lang/en_utf8/quiz.php
index 82d879647ac..ef2786b58b0 100644
--- a/lang/en_utf8/quiz.php
+++ b/lang/en_utf8/quiz.php
@@ -10,6 +10,18 @@ $string['action'] = 'Action';
$string['adaptive'] = 'Adaptive mode';
$string['addcategory'] = 'Add category';
$string['addingquestions'] = 'This side of the page is where you manage your database of questions. Questions are stored in categories to help you keep them organised, and can be used by any quiz in your course or even other courses if you choose to \'publish\' them.
After you select or create a question category you will be able to create or edit questions. You can select any of these questions to add to your quiz over on the other side of this page.';
+$string['addingcalculated'] = 'Adding a Calculated question';
+$string['addingdescription'] = 'Adding a Description';
+$string['addingessay'] = 'Adding Essay';
+$string['addingmatch'] = 'Adding a Matching Question';
+$string['addingmultianswer'] = 'Adding Embedded Answers (Cloze)';
+$string['addingmultichoice'] = 'Adding a Multiple Choice question';
+$string['addingnumerical'] = 'Adding a Numerical question';
+$string['addingquestion'] = 'Adding a question';
+$string['addingrandom'] = 'Adding a Random Question';
+$string['addingrandomsamatch'] = 'Adding a Random Short-Answer Matching question';
+$string['addingshortanswer'] = 'Adding a Short-Answer question';
+$string['addingtruefalse'] = 'Adding a True/False question';
$string['addquestions'] = 'Add questions';
$string['addquestionstoquiz'] = 'Add questions to current quiz';
$string['addrandom'] = 'Add $a random questions';
@@ -404,7 +416,7 @@ $string['quiz:deleteattempts'] = 'Delete quiz attempts';
$string['quiz:emailconfirmsubmission'] = 'Get email confirmation when submitting';
$string['quiz:emailnotifysubmission'] = 'Get email notification of submissions';
$string['quiz:grade'] = 'Grade quizzes manually';
-$string['quiz:ignoretimelimits'] = 'Ignores time limit on quizzes';
+$string['quiz:ignoretimelimits'] = 'Ignores time limit on quizs';
$string['quiz:manage'] = 'Manage quizzes';
$string['quiz:preview'] = 'Preview quizzes';
$string['quiz:view'] = 'View quiz information';
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 5d115fff4d4..d1ec05260ef 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -3017,6 +3017,7 @@ function delete_course($courseid, $showfeedback = true) {
*/
function remove_course_contents($courseid, $showfeedback=true) {
+ include_once($CFG->libdir.'/questionlib.php');
global $CFG;
$result = true;
@@ -3042,6 +3043,8 @@ function remove_course_contents($courseid, $showfeedback=true) {
if ($instances = get_records($modname, 'course', $course->id)) {
foreach ($instances as $instance) {
if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
+ /// Delete activity context questions and question categories
+ question_delete_activity($cm, $showfeedback);
delete_context(CONTEXT_MODULE, $cm->id);
}
if ($moddelete($instance->id)) {
@@ -3187,7 +3190,6 @@ function remove_course_contents($courseid, $showfeedback=true) {
}
/// Delete questions and question categories
- include_once($CFG->libdir.'/questionlib.php');
question_delete_course($course, $showfeedback);
/// Delete all roles and overiddes in the course context (but keep the course context)
diff --git a/lib/questionlib.php b/lib/questionlib.php
index f118679e157..a3162906e2d 100644
--- a/lib/questionlib.php
+++ b/lib/questionlib.php
@@ -87,6 +87,16 @@ 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);
+
/**#@-*/
/// QTYPES INITIATION //////////////////
@@ -373,7 +383,7 @@ function delete_attempt($attemptid) {
$states = get_records('question_states', 'attempt', $attemptid);
if ($states) {
$stateslist = implode(',', array_keys($states));
-
+
// delete question-type specific data
foreach ($QTYPES as $qtype) {
$qtype->delete_states($stateslist);
@@ -402,7 +412,9 @@ function delete_question($questionid) {
}
// delete questiontype-specific data
- if ($question = get_record('question', 'id', $questionid)) {
+ $question = get_record('question', 'id', $questionid);
+ question_require_capability_on($question, 'edit');
+ if ($question) {
if (isset($QTYPES[$question->qtype])) {
$QTYPES[$question->qtype]->delete_question($questionid);
}
@@ -441,106 +453,42 @@ function delete_question($questionid) {
}
/**
- * All non-used question categories and their questions are deleted and
- * categories still used by other courses are moved to the site course.
+ * All question categories and their questions are deleted for this course.
*
- * @param object $course an object representing the course
+ * @param object $mod an object representing the activity
* @param boolean $feedback to specify if the process must output a summary of its work
* @return boolean
*/
function question_delete_course($course, $feedback=true) {
-
- global $CFG, $QTYPES;
-
- //To detect if we have created the "container category"
- $concatid = 0;
-
- //The "container" category we'll create if we need if
- $contcat = new object;
-
- //To temporary store changes performed with parents
- $parentchanged = array();
-
//To store feedback to be showed at the end of the process
$feedbackdata = array();
//Cache some strings
- $strcatcontainer=get_string('containercategorycreated', 'quiz');
- $strcatmoved = get_string('usedcategorymoved', 'quiz');
$strcatdeleted = get_string('unusedcategorydeleted', 'quiz');
+ $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+ $categoriescourse = get_records('question_categories', 'contextid', $coursecontext->id, 'parent', 'id, parent, name');
- if ($categories = get_records('question_categories', 'course', $course->id, 'parent', 'id, parent, name, course')) {
+ if ($categoriescourse) {
//Sort categories following their tree (parent-child) relationships
- $categories = sort_categories_by_tree($categories);
+ //this will make the feedback more readable
+ $categoriescourse = sort_categories_by_tree($categoriescourse);
- foreach ($categories as $cat) {
+ foreach ($categoriescourse as $category) {
- //Get the full record
- $category = get_record('question_categories', 'id', $cat->id);
-
- //Check if the category is being used anywhere
- if(question_category_isused($category->id, true)) {
- //It's being used. Cannot delete it, so:
- //Create a container category in SITEID course if it doesn't exist
- if (!$concatid) {
- $concat = new stdClass;
- $concat->course = SITEID;
- if (!isset($course->shortname)) {
- $course->shortname = 'id=' . $course->id;
- }
- $concat->name = get_string('savedfromdeletedcourse', 'quiz', format_string($course->shortname));
- $concat->info = $concat->name;
- $concat->publish = 1;
- $concat->stamp = make_unique_id_code();
- $concatid = insert_record('question_categories', $concat);
-
- //Fill feedback
- $feedbackdata[] = array($concat->name, $strcatcontainer);
+ //Delete it completely (questions and category itself)
+ //deleting questions
+ if ($questions = get_records("question", "category", $category->id)) {
+ foreach ($questions as $question) {
+ delete_question($question->id);
}
- //Move the category to the container category in SITEID course
- $category->course = SITEID;
- //Assign to container if the category hasn't parent or if the parent is wrong (not belongs to the course)
- if (!$category->parent || !isset($categories[$category->parent])) {
- $category->parent = $concatid;
- }
- //If it's being used, its publish field should be 1
- $category->publish = 1;
- //Let's update it
- update_record('question_categories', $category);
-
- //Save this parent change for future use
- $parentchanged[$category->id] = $category->parent;
-
- //Fill feedback
- $feedbackdata[] = array($category->name, $strcatmoved);
-
- } else {
- //Category isn't being used so:
- //Delete it completely (questions and category itself)
- //deleting questions
- if ($questions = get_records("question", "category", $category->id)) {
- foreach ($questions as $question) {
- delete_question($question->id);
- }
- delete_records("question", "category", $category->id);
- }
- //delete the category
- delete_records('question_categories', 'id', $category->id);
-
- //Save this parent change for future use
- if (!empty($category->parent)) {
- $parentchanged[$category->id] = $category->parent;
- } else {
- $parentchanged[$category->id] = $concatid;
- }
-
- //Update all its child categories to re-parent them to grandparent.
- set_field ('question_categories', 'parent', $parentchanged[$category->id], 'parent', $category->id);
-
- //Fill feedback
- $feedbackdata[] = array($category->name, $strcatdeleted);
+ delete_records("question", "category", $category->id);
}
+ //delete the category
+ delete_records('question_categories', 'id', $category->id);
+
+ //Fill feedback
+ $feedbackdata[] = array($category->name, $strcatdeleted);
}
//Inform about changes performed if feedback is enabled
if ($feedback) {
@@ -553,22 +501,67 @@ function question_delete_course($course, $feedback=true) {
return true;
}
-function questionbank_navigation_tabs(&$row, $context, $querystring) {
- global $CFG;
- if (has_capability('moodle/question:manage', $context)) {
- $row[] = new tabobject('questions', "$CFG->wwwroot/question/edit.php?$querystring", get_string('questions', 'quiz'), get_string('editquestions', "quiz"));
+/**
+ * All question categories and their questions are deleted for this activity.
+ *
+ * @param object $cm the course module object representing the activity
+ * @param boolean $feedback to specify if the process must output a summary of its work
+ * @return boolean
+ */
+function question_delete_activity($cm, $feedback=true) {
+ //To store feedback to be showed at the end of the process
+ $feedbackdata = array();
+
+ //Cache some strings
+ $strcatdeleted = get_string('unusedcategorydeleted', 'quiz');
+ $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+ if ($categoriesmods = get_records('question_categories', 'contextid', $modcontext->id, 'parent', 'id, parent, name')){
+ //Sort categories following their tree (parent-child) relationships
+ //this will make the feedback more readable
+ $categoriesmods = sort_categories_by_tree($categoriesmods);
+
+ foreach ($categoriesmods as $category) {
+
+ //Delete it completely (questions and category itself)
+ //deleting questions
+ if ($questions = get_records("question", "category", $category->id)) {
+ foreach ($questions as $question) {
+ delete_question($question->id);
+ }
+ delete_records("question", "category", $category->id);
+ }
+ //delete the category
+ delete_records('question_categories', 'id', $category->id);
+
+ //Fill feedback
+ $feedbackdata[] = array($category->name, $strcatdeleted);
+ }
+ //Inform about changes performed if feedback is enabled
+ if ($feedback) {
+ $table = new stdClass;
+ $table->head = array(get_string('category','quiz'), get_string('action'));
+ $table->data = $feedbackdata;
+ print_table($table);
+ }
}
-
- if (has_capability('moodle/question:managecategory', $context)) {
- $row[] = new tabobject('categories', "$CFG->wwwroot/question/category.php?$querystring", get_string('categories', 'quiz'), get_string('editqcats', 'quiz'));
- }
-
- if (has_capability('moodle/question:import', $context)) {
- $row[] = new tabobject('import', "$CFG->wwwroot/question/import.php?$querystring", get_string('import', 'quiz'), get_string('importquestions', 'quiz'));
- }
-
- if (has_capability('moodle/question:export', $context)) {
- $row[] = new tabobject('export', "$CFG->wwwroot/question/export.php?$querystring", get_string('export', 'quiz'), get_string('exportquestions', 'quiz'));
+ return true;
+}
+/**
+ * @param array $row tab objects
+ * @param question_edit_contexts $contexts object representing contexts available from this context
+ * @param string $querystring to append to urls
+ * */
+function questionbank_navigation_tabs(&$row, $contexts, $querystring) {
+ global $CFG, $QUESTION_EDITTABCAPS;
+ $tabs = array(
+ 'questions' =>array("$CFG->wwwroot/question/edit.php?$querystring", get_string('questions', 'quiz'), get_string('editquestions', 'quiz')),
+ 'categories' =>array("$CFG->wwwroot/question/category.php?$querystring", get_string('categories', 'quiz'), get_string('editqcats', 'quiz')),
+ 'import' =>array("$CFG->wwwroot/question/import.php?$querystring", get_string('import', 'quiz'), get_string('importquestions', 'quiz')),
+ 'export' =>array("$CFG->wwwroot/question/export.php?$querystring", get_string('export', 'quiz'), get_string('exportquestions', 'quiz')));
+ foreach ($tabs as $tabname => $tabparams){
+ if ($contexts->have_one_edit_tab_cap($tabname)) {
+ $row[] = new tabobject($tabname, $tabparams[0], $tabparams[1], $tabparams[2]);
+ }
}
}
@@ -712,7 +705,7 @@ function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid =
$states[$i]->sumpenalty = 0;
$states[$i]->manualcomment = '';
- // if building on last attempt we want to preserve responses
+ // if building on last attempt we want to preserve responses
if (!$lastattemptid) {
$states[$i]->responses = array('' => '');
}
@@ -731,7 +724,7 @@ function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid =
question_process_responses($questions[$i], $states[$i], $action, $cmoptions, $attempt);
// Fix for Bug #5506: When each attempt is built on the last one,
- // preserve the options from any previous attempt.
+ // preserve the options from any previous attempt.
if ( isset($laststate->options) ) {
$states[$i]->options = $laststate->options;
}
@@ -1161,7 +1154,7 @@ function question_process_responses(&$question, &$state, $action, $cmoptions, &$
if (!question_isgradingevent($action->event)) {
// Grade the response but don't update the overall grade
$QTYPES[$question->qtype]->grade_responses($question, $state, $cmoptions);
-
+
// Temporary hack because question types are not given enough control over what is going
// on. Used by Opaque questions.
// TODO fix this code properly.
@@ -1173,7 +1166,7 @@ function question_process_responses(&$question, &$state, $action, $cmoptions, &$
// update the attempt grade
$attempt->sumgrades -= (float)$state->last_graded->grade;
$attempt->sumgrades += (float)$state->grade;
-
+
// and update the last_graded field.
unset($state->last_graded);
$state->last_graded = clone($state);
@@ -1183,7 +1176,7 @@ function question_process_responses(&$question, &$state, $action, $cmoptions, &$
// Don't allow the processing to change the event type
$state->event = $action->event;
}
-
+
} else { // grading event
// Unless the attempt is closing, we want to work out if the current responses
@@ -1248,7 +1241,7 @@ function question_isgradingevent($event) {
function question_apply_penalty_and_timelimit(&$question, &$state, $attempt, $cmoptions) {
// TODO. Quiz dependancy. The fact that the attempt that is passed in here
// is from quiz_attempts, and we use things like $cmoptions->timelimit.
-
+
// deal with penalty
if ($cmoptions->penaltyscheme) {
$state->grade = $state->raw_grade - $state->sumpenalty;
@@ -1589,7 +1582,7 @@ function sort_categories_by_tree(&$categories, $id = 0, $level = 1) {
* @param int $depth the indent depth. Used in recursive calls.
* @return array a new array of categories, in the right order for the tree.
*/
-function flatten_category_tree(&$categories, $id, $depth = 0) {
+function flatten_category_tree(&$categories, $id, $depth = 0, $nochildrenof = -1) {
// Indent the name of this category.
$newcategories = array();
@@ -1598,7 +1591,9 @@ function flatten_category_tree(&$categories, $id, $depth = 0) {
// Recursively indent the children.
foreach ($categories[$id]->childids as $childid) {
- $newcategories = $newcategories + flatten_category_tree($categories, $childid, $depth + 1);
+ if ($childid != $nochildrenof){
+ $newcategories = $newcategories + flatten_category_tree($categories, $childid, $depth + 1, $nochildrenof);
+ }
}
// Remove the childids array that were temporarily added.
@@ -1613,7 +1608,7 @@ function flatten_category_tree(&$categories, $id, $depth = 0) {
* @param array $categories An array of category objects, for example from the.
* @return array The formatted list of categories.
*/
-function add_indented_names($categories) {
+function add_indented_names($categories, $nochildrenof = -1) {
// Add an array to each category to hold the child category ids. This array will be removed
// again by flatten_category_tree(). It should not be used outside these two functions.
@@ -1636,7 +1631,7 @@ function add_indented_names($categories) {
// Flatten the tree to and add the indents.
$newcategories = array();
foreach ($toplevelcategoryids as $id) {
- $newcategories = $newcategories + flatten_category_tree($categories, $id);
+ $newcategories = $newcategories + flatten_category_tree($categories, $id, 0, $nochildrenof);
}
return $newcategories;
@@ -1653,70 +1648,102 @@ function add_indented_names($categories) {
* @param integer $only_editable if true, exclude categories this user is not allowed to edit.
* @param integer $selected optionally, the id of a category to be selected by default in the dropdown.
*/
-function question_category_select_menu($courseid, $published = false, $only_editable = false, $selected = "") {
- $categoriesarray = question_category_options($courseid, $published, $only_editable);
+function question_category_select_menu($contexts, $top = false, $currentcat = 0, $selected = "", $nochildrenof = -1) {
+ $categoriesarray = question_category_options($contexts, $top, $currentcat, false, $nochildrenof);
if ($selected) {
$nothing = '';
} else {
$nothing = 'choose';
}
- choose_from_menu($categoriesarray, 'category', $selected, $nothing);
+ choose_from_menu_nested($categoriesarray, 'category', $selected, $nothing);
+}
+
+/**
+ * Get all the category objects, including a count of the number of questions in that category,
+ * for all the categories in the lists $contexts.
+ *
+ * @param mixed $contexts either a single contextid, or a comma-separated list of context ids.
+ * @param string $sortorder used as the ORDER BY clause in the select statement.
+ * @return array of category objects.
+ */
+function get_categories_for_contexts($contexts, $sortorder = 'parent, sortorder, name ASC') {
+ global $CFG;
+ return get_records_sql("
+ SELECT *, (SELECT count(1) FROM {$CFG->prefix}question q
+ WHERE c.id = q.category AND q.hidden='0' AND q.parent='0') as questioncount
+ FROM {$CFG->prefix}question_categories as c
+ WHERE c.contextid IN ($contexts)
+ ORDER BY $sortorder");
}
/**
* Output an array of question categories.
- *
- * Categories from this course and (optionally) published categories from other courses
- * are included. Optionally, only categories the current user may edit can be included.
- *
- * @param integer $courseid the id of the course to get the categories for.
- * @param integer $published if true, include publised categories from other courses.
- * @param integer $only_editable if true, exclude categories this user is not allowed to edit.
- * @return array The list of categories.
*/
-function question_category_options($courseid, $published = false, $only_editable = false) {
+function question_category_options($contexts, $top = false, $currentcat = 0, $popupform = false, $nochildrenof = -1) {
global $CFG;
-
- // get sql fragment for published
- $publishsql="";
- if ($published) {
- $publishsql = " OR publish = 1";
+ $pcontexts = array();
+ foreach($contexts as $context){
+ $pcontexts[] = $context->id;
}
+ $contextslist = join($pcontexts, ', ');
- $categories = get_records_sql("
- SELECT cat.*, c.shortname AS coursename
- FROM {$CFG->prefix}question_categories cat, {$CFG->prefix}course c
- WHERE c.id = cat.course AND (cat.course = $courseid $publishsql)
- ORDER BY (CASE WHEN cat.course = $courseid THEN 0 ELSE 1 END), cat.parent, cat.sortorder, cat.name ASC");
- $categories = add_indented_names($categories);
+ $categories = get_categories_for_contexts($contextslist);
+ $categories = question_add_context_in_key($categories);
+
+ if ($top){
+ $categories = question_add_tops($categories, $pcontexts);
+ }
+ $categories = add_indented_names($categories, $nochildrenof);
+
+ //sort cats out into different contexts
$categoriesarray = array();
- foreach ($categories as $category) {
- $cid = $category->id;
- $cname = question_category_coursename($category, $courseid);
- if ((!$only_editable) || has_capability('moodle/question:managecategory', get_context_instance(CONTEXT_COURSE, $category->course))) {
- $categoriesarray[$cid] = $cname;
+ foreach ($pcontexts as $pcontext){
+ $contextstring = print_context_name(get_context_instance_by_id($pcontext), true, true);
+ foreach ($categories as $category) {
+ if ($category->contextid == $pcontext){
+ $cid = $category->id;
+ if ($currentcat!= $cid || $currentcat==0) {
+ $countstring = (!empty($category->questioncount))?"($category->questioncount)":'';
+ $categoriesarray[$contextstring][$cid] = $category->indentedname.$countstring;
+ }
+ }
}
}
- return $categoriesarray;
+ if ($popupform){
+ $popupcats = array();
+ foreach ($categoriesarray as $contextstring => $optgroup){
+ $popupcats[] = '--'.$contextstring;
+ $popupcats = array_merge($popupcats, $optgroup);
+ $popupcats[] = '--';
+ }
+ return $popupcats;
+ } else {
+ return $categoriesarray;
+ }
}
-/**
- * If the category is not from this course, and it is a published category,
- * then return the course category name with the course shortname appended in
- * brackets. Otherwise, just return the category name.
- */
-function question_category_coursename($category, $courseid = 0) {
- $cname = (isset($category->indentedname)) ? $category->indentedname : $category->name;
- if ($category->course != $courseid && $category->publish) {
- if (!empty($category->coursename)) {
- $coursename = $category->coursename;
- } else {
- $coursename = get_field('course', 'shortname', 'id', $category->course);
- }
- $cname .= " ($coursename)";
+function question_add_context_in_key($categories){
+ $newcatarray = array();
+ foreach ($categories as $id => $category) {
+ $category->parent = "$category->parent,$category->contextid";
+ $category->id = "$category->id,$category->contextid";
+ $newcatarray["$id,$category->contextid"] = $category;
}
- return $cname;
+ return $newcatarray;
+}
+function question_add_tops($categories, $pcontexts){
+ $topcats = array();
+ foreach ($pcontexts as $context){
+ $newcat = new object();
+ $newcat->id = "0,$context";
+ $newcat->name = get_string('top');
+ $newcat->parent = -1;
+ $newcat->contextid = $context;
+ $topcats["0,$context"] = $newcat;
+ }
+ //put topcats in at beginning of array - they'll be sorted into different contexts later.
+ return array_merge($topcats, $categories);
}
/**
@@ -1733,67 +1760,8 @@ function question_categorylist($categoryid) {
return $categorylist;
}
-/**
- * find and/or create the category described by a delimited list
- * e.g. tom/dick/harry
- * @param string catpath delimited category path
- * @param string delimiter path delimiting character
- * @param int courseid course to search for categories
- * @return mixed category object or null if fails
- */
-function create_category_path( $catpath, $delimiter='/', $courseid=0 ) {
- $catpath = clean_param( $catpath,PARAM_PATH );
- $catnames = explode( $delimiter, $catpath );
- $parent = 0;
- $category = null;
- foreach ($catnames as $catname) {
- if ($category = get_record( 'question_categories', 'name', $catname, 'course', $courseid, 'parent', $parent )) {
- $parent = $category->id;
- }
- else {
- // create the new category
- $category = new object;
- $category->course = $courseid;
- $category->name = $catname;
- $category->info = '';
- $category->publish = false;
- $category->parent = $parent;
- $category->sortorder = 999;
- $category->stamp = make_unique_id_code();
- if (!($id = insert_record( 'question_categories', $category ))) {
- error( "cannot create new category - $catname" );
- }
- $category->id = $id;
- $parent = $id;
- }
- }
- return $category;
-}
-/**
- * get the category as a path (e.g., tom/dick/harry)
- * @param int id the id of the most nested catgory
- * @param string delimiter the delimiter you want
- * @return string the path
- */
-function get_category_path( $id, $delimiter='/' ) {
- $path = '';
- do {
- if (!$category = get_record( 'question_categories','id',$id )) {
- print_error( "Error reading category record - $id" );
- }
- $name = $category->name;
- $id = $category->parent;
- if (!empty($path)) {
- $path = "{$name}{$delimiter}{$path}";
- }
- else {
- $path = $name;
- }
- } while ($id != 0);
-
- return $path;
-}
+
//===========================
// Import/Export Functions
@@ -1887,5 +1855,213 @@ function default_export_filename($course,$category) {
return $export_name;
}
+class context_to_string_translator{
+ /**
+ * @var array used to translate between contextids and strings for this context.
+ */
+ var $contexttostringarray = array();
+ function context_to_string_translator($contexts){
+ $this->generate_context_to_string_array($contexts);
+ }
+
+ function context_to_string($contextid){
+ return $this->contexttostringarray[$contextid];
+ }
+
+ function string_to_context($contextname){
+ $contextid = array_search($contextname, $this->contexttostringarray);
+ return $contextid;
+ }
+
+ function generate_context_to_string_array($contexts){
+ if (!$this->contexttostringarray){
+ $catno = 1;
+ foreach ($contexts as $context){
+ switch ($context->contextlevel){
+ case CONTEXT_MODULE :
+ $contextstring = 'module';
+ break;
+ case CONTEXT_COURSE :
+ $contextstring = 'course';
+ break;
+ case CONTEXT_COURSECAT :
+ $contextstring = "cat$catno";
+ $catno++;
+ break;
+ case CONTEXT_SYSTEM :
+ $contextstring = 'system';
+ break;
+ }
+ $this->contexttostringarray[$context->id] = $contextstring;
+ }
+ }
+ }
+
+}
+
+
+/**
+ * Check capability on category
+ * @param mixed $question object or id
+ * @param string $cap 'add', 'edit', 'view', 'use', 'move'
+ * @param integer $cachecat useful to cache all question records in a category
+ * @return boolean this user has the capability $cap for this question $question?
+ */
+function question_has_capability_on($question, $cap, $cachecat = -1){
+ global $USER;
+ // these are capabilities on existing questions capabilties are
+ //set per category. Each of these has a mine and all version. Append 'mine' and 'all'
+ $question_questioncaps = array('edit', 'view', 'use', 'move');
+
+ static $questions = array();
+ static $categories = array();
+ static $cachedcat = array();
+ if ($cachecat != -1 && (array_search($cachecat, $cachedcat)!==FALSE)){
+ $questions += get_records('question', 'category', $cachecat);
+ $cachedcat[] = $cachecat;
+ }
+ if (!is_object($question)){
+ if (!isset($questions[$question])){
+ if (!$questions[$question] = get_record('question', 'id', $question)){
+ print_error('invalidcategory', 'quiz');
+ }
+ }
+ $question = $questions[$question];
+ }
+ if (!isset($categories[$question->category])){
+ if (!$categories[$question->category] = get_record('question_categories', 'id', $question->category)){
+ print_error('invalidcategory', 'quiz');
+ }
+ }
+ $category = $categories[$question->category];
+
+ if (array_search($cap, $question_questioncaps)!== FALSE){
+ if (!has_capability('moodle/question:'.$cap.'all', get_context_instance_by_id($category->contextid))){
+ if ($question->createdby == $USER->id){
+ return has_capability('moodle/question:'.$cap.'mine', get_context_instance_by_id($category->contextid));
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ } else {
+ return has_capability('moodle/question:'.$cap, get_context_instance_by_id($category->contextid));
+ }
+
+}
+
+/**
+ * Require capability on question.
+ */
+function question_require_capability_on($question, $cap){
+ if (!question_has_capability_on($question, $cap)){
+ print_error('nopermissions', '', '', $cap);
+ }
+ return true;
+}
+
+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.
+ * @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
+ *
+ * @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.
+ * @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;
+ if ($CFG->slasharguments) { // Use this method if possible for better caching
+ $tourl = "$CFG->wwwroot/file.php/$tocourseid/$destination";
+
+ } else {
+ $tourl = "$CFG->wwwroot/file.php?file=/$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;
+}
+
+function get_filesdir_from_context($context){
+ switch ($context->contextlevel){
+ case CONTEXT_COURSE :
+ $courseid = $context->instanceid;
+ break;
+ case CONTEXT_MODULE :
+ $courseid = get_field('course_modules', 'course', 'id', $context->instanceid);
+ break;
+ case CONTEXT_COURSECAT :
+ case CONTEXT_SYSTEM :
+ $courseid = SITEID;
+ break;
+ default :
+ error('Unsupported contextlevel in category record!');
+ }
+ return $courseid;
+}
?>
|