PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/assignment/restorelib.php

https://bitbucket.org/ceu/moodle_demo
PHP | 515 lines | 342 code | 60 blank | 113 comment | 72 complexity | dfa67d776413e7f39f1792bcb4a7f5c4 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, LGPL-2.1
  1. <?php //$Id: restorelib.php,v 1.33.2.6 2009/08/15 07:58:36 mjollnir_ Exp $
  2. //This php script contains all the stuff to backup/restore
  3. //assignment mods
  4. //This is the "graphical" structure of the assignment mod:
  5. //
  6. // assignment
  7. // (CL,pk->id)
  8. // |
  9. // |
  10. // |
  11. // assignment_submisions
  12. // (UL,pk->id, fk->assignment,files)
  13. //
  14. // Meaning: pk->primary key field of the table
  15. // fk->foreign key to link with parent
  16. // nt->nested field (recursive data)
  17. // CL->course level info
  18. // UL->user level info
  19. // files->table may have files)
  20. //
  21. //-----------------------------------------------------------
  22. //This function executes all the restore procedure about this mod
  23. function assignment_restore_mods($mod,$restore) {
  24. global $CFG;
  25. $status = true;
  26. //Get record from backup_ids
  27. $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
  28. if ($data) {
  29. //Now get completed xmlized object
  30. $info = $data->info;
  31. //if necessary, write to restorelog and adjust date/time fields
  32. if ($restore->course_startdateoffset) {
  33. restore_log_date_changes('Assignment', $restore, $info['MOD']['#'], array('TIMEDUE', 'TIMEAVAILABLE'));
  34. }
  35. //traverse_xmlize($info); //Debug
  36. //print_object ($GLOBALS['traverse_array']); //Debug
  37. //$GLOBALS['traverse_array']=""; //Debug
  38. //Now, build the ASSIGNMENT record structure
  39. $assignment->course = $restore->course_id;
  40. $assignment->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
  41. $assignment->description = backup_todb($info['MOD']['#']['DESCRIPTION']['0']['#']);
  42. $assignment->format = backup_todb($info['MOD']['#']['FORMAT']['0']['#']);
  43. $assignment->resubmit = backup_todb($info['MOD']['#']['RESUBMIT']['0']['#']);
  44. $assignment->preventlate = backup_todb($info['MOD']['#']['PREVENTLATE']['0']['#']);
  45. $assignment->emailteachers = backup_todb($info['MOD']['#']['EMAILTEACHERS']['0']['#']);
  46. $assignment->var1 = backup_todb($info['MOD']['#']['VAR1']['0']['#']);
  47. $assignment->var2 = backup_todb($info['MOD']['#']['VAR2']['0']['#']);
  48. $assignment->var3 = backup_todb($info['MOD']['#']['VAR3']['0']['#']);
  49. $assignment->var4 = backup_todb($info['MOD']['#']['VAR4']['0']['#']);
  50. $assignment->var5 = backup_todb($info['MOD']['#']['VAR5']['0']['#']);
  51. $assignment->type = isset($info['MOD']['#']['TYPE']['0']['#'])?backup_todb($info['MOD']['#']['TYPE']['0']['#']):'';
  52. $assignment->assignmenttype = backup_todb($info['MOD']['#']['ASSIGNMENTTYPE']['0']['#']);
  53. $assignment->maxbytes = backup_todb($info['MOD']['#']['MAXBYTES']['0']['#']);
  54. $assignment->timedue = backup_todb($info['MOD']['#']['TIMEDUE']['0']['#']);
  55. $assignment->timeavailable = backup_todb($info['MOD']['#']['TIMEAVAILABLE']['0']['#']);
  56. $assignment->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']);
  57. $assignment->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
  58. //We have to recode the grade field if it is <0 (scale)
  59. if ($assignment->grade < 0) {
  60. $scale = backup_getid($restore->backup_unique_code,"scale",abs($assignment->grade));
  61. if ($scale) {
  62. $assignment->grade = -($scale->new_id);
  63. }
  64. }
  65. if (empty($assignment->assignmenttype)) { /// Pre 1.5 assignment
  66. if ($assignment->type == 1) {
  67. $assignment->assignmenttype = 'uploadsingle';
  68. } else {
  69. $assignment->assignmenttype = 'offline';
  70. }
  71. }
  72. // skip restore of plugins that are not installed
  73. static $plugins;
  74. if (!isset($plugins)) {
  75. $plugins = get_list_of_plugins('mod/assignment/type');
  76. }
  77. if (!in_array($assignment->assignmenttype, $plugins)) {
  78. if (!defined('RESTORE_SILENTLY')) {
  79. echo "<li><strong>".get_string("modulename","assignment")." \"".format_string(stripslashes($assignment->name),true)."\" - plugin '{$assignment->assignmenttype}' not available!</strong></li>";
  80. }
  81. return true; // do not fail the restore
  82. }
  83. //The structure is equal to the db, so insert the assignment
  84. $newid = insert_record ("assignment",$assignment);
  85. //Do some output
  86. if (!defined('RESTORE_SILENTLY')) {
  87. echo "<li>".get_string("modulename","assignment")." \"".format_string(stripslashes($assignment->name),true)."\"</li>";
  88. }
  89. backup_flush(300);
  90. if ($newid) {
  91. //We have the newid, update backup_ids
  92. backup_putid($restore->backup_unique_code,$mod->modtype,
  93. $mod->id, $newid);
  94. // load up the subtype and see if it wants anything further restored.
  95. $class = 'assignment_' . $assignment->assignmenttype;
  96. require_once($CFG->dirroot . '/mod/assignment/lib.php');
  97. require_once($CFG->dirroot . '/mod/assignment/type/' . $assignment->assignmenttype . '/assignment.class.php');
  98. call_user_func(array($class, 'restore_one_mod'), $info, $restore, $assignment);
  99. //Now check if want to restore user data and do it.
  100. if (restore_userdata_selected($restore,'assignment',$mod->id)) {
  101. //Restore assignmet_submissions
  102. $status = assignment_submissions_restore_mods($mod->id, $newid,$info,$restore, $assignment) && $status;
  103. }
  104. } else {
  105. $status = false;
  106. }
  107. } else {
  108. $status = false;
  109. }
  110. return $status;
  111. }
  112. //This function restores the assignment_submissions
  113. function assignment_submissions_restore_mods($old_assignment_id, $new_assignment_id,$info,$restore, $assignment) {
  114. global $CFG;
  115. $status = true;
  116. //Get the submissions array - it might not be present
  117. if (isset($info['MOD']['#']['SUBMISSIONS']['0']['#']['SUBMISSION'])) {
  118. $submissions = $info['MOD']['#']['SUBMISSIONS']['0']['#']['SUBMISSION'];
  119. } else {
  120. $submissions = array();
  121. }
  122. //Iterate over submissions
  123. for($i = 0; $i < sizeof($submissions); $i++) {
  124. $sub_info = $submissions[$i];
  125. //traverse_xmlize($sub_info); //Debug
  126. //print_object ($GLOBALS['traverse_array']); //Debug
  127. //$GLOBALS['traverse_array']=""; //Debug
  128. //We'll need this later!!
  129. $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
  130. $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
  131. //Now, build the ASSIGNMENT_SUBMISSIONS record structure
  132. $submission->assignment = $new_assignment_id;
  133. $submission->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
  134. $submission->timecreated = backup_todb($sub_info['#']['TIMECREATED']['0']['#']);
  135. $submission->timemodified = backup_todb($sub_info['#']['TIMEMODIFIED']['0']['#']);
  136. $submission->numfiles = backup_todb($sub_info['#']['NUMFILES']['0']['#']);
  137. $submission->data1 = backup_todb($sub_info['#']['DATA1']['0']['#']);
  138. $submission->data2 = backup_todb($sub_info['#']['DATA2']['0']['#']);
  139. $submission->grade = backup_todb($sub_info['#']['GRADE']['0']['#']);
  140. if (isset($sub_info['#']['COMMENT']['0']['#'])) {
  141. $submission->submissioncomment = backup_todb($sub_info['#']['COMMENT']['0']['#']);
  142. } else {
  143. $submission->submissioncomment = backup_todb($sub_info['#']['SUBMISSIONCOMMENT']['0']['#']);
  144. }
  145. $submission->format = backup_todb($sub_info['#']['FORMAT']['0']['#']);
  146. $submission->teacher = backup_todb($sub_info['#']['TEACHER']['0']['#']);
  147. $submission->timemarked = backup_todb($sub_info['#']['TIMEMARKED']['0']['#']);
  148. $submission->mailed = backup_todb($sub_info['#']['MAILED']['0']['#']);
  149. //We have to recode the userid field
  150. $user = backup_getid($restore->backup_unique_code,"user",$submission->userid);
  151. if ($user) {
  152. $submission->userid = $user->new_id;
  153. }
  154. //We have to recode the teacher field
  155. $user = backup_getid($restore->backup_unique_code,"user",$submission->teacher);
  156. if ($user) {
  157. $submission->teacher = $user->new_id;
  158. }
  159. //The structure is equal to the db, so insert the assignment_submission
  160. $newid = insert_record ("assignment_submissions",$submission);
  161. //Do some output
  162. if (($i+1) % 50 == 0) {
  163. if (!defined('RESTORE_SILENTLY')) {
  164. echo ".";
  165. if (($i+1) % 1000 == 0) {
  166. echo "<br />";
  167. }
  168. }
  169. backup_flush(300);
  170. }
  171. if ($newid) {
  172. //We have the newid, update backup_ids
  173. backup_putid($restore->backup_unique_code,"assignment_submission",$oldid,
  174. $newid);
  175. //Now copy moddata associated files
  176. $status = assignment_restore_files ($old_assignment_id, $new_assignment_id,
  177. $olduserid, $submission->userid, $restore);
  178. $submission->id = $newid;
  179. $class = 'assignment_' . $assignment->assignmenttype;
  180. require_once($CFG->dirroot . '/mod/assignment/lib.php');
  181. require_once($CFG->dirroot . '/mod/assignment/type/' . $assignment->assignmenttype . '/assignment.class.php');
  182. call_user_func(array($class, 'restore_one_submission'), $sub_info, $restore, $assignment, $submission);
  183. } else {
  184. $status = false;
  185. }
  186. }
  187. return $status;
  188. }
  189. //This function copies the assignment related info from backup temp dir to course moddata folder,
  190. //creating it if needed and recoding everything (assignment id and user id)
  191. function assignment_restore_files ($oldassid, $newassid, $olduserid, $newuserid, $restore) {
  192. global $CFG;
  193. $status = true;
  194. $todo = false;
  195. $moddata_path = "";
  196. $assignment_path = "";
  197. $temp_path = "";
  198. //First, we check to "course_id" exists and create is as necessary
  199. //in CFG->dataroot
  200. $dest_dir = $CFG->dataroot."/".$restore->course_id;
  201. $status = check_dir_exists($dest_dir,true);
  202. //Now, locate course's moddata directory
  203. $moddata_path = $CFG->dataroot."/".$restore->course_id."/".$CFG->moddata;
  204. //Check it exists and create it
  205. $status = check_dir_exists($moddata_path,true);
  206. //Now, locate assignment directory
  207. if ($status) {
  208. $assignment_path = $moddata_path."/assignment";
  209. //Check it exists and create it
  210. $status = check_dir_exists($assignment_path,true);
  211. }
  212. //Now locate the temp dir we are gong to restore
  213. if ($status) {
  214. $temp_path = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code.
  215. "/moddata/assignment/".$oldassid."/".$olduserid;
  216. //Check it exists
  217. if (is_dir($temp_path)) {
  218. $todo = true;
  219. }
  220. }
  221. //If todo, we create the neccesary dirs in course moddata/assignment
  222. if ($status and $todo) {
  223. //First this assignment id
  224. $this_assignment_path = $assignment_path."/".$newassid;
  225. $status = check_dir_exists($this_assignment_path,true);
  226. //Now this user id
  227. $user_assignment_path = $this_assignment_path."/".$newuserid;
  228. //And now, copy temp_path to user_assignment_path
  229. $status = backup_copy_file($temp_path, $user_assignment_path);
  230. }
  231. return $status;
  232. }
  233. //Return a content decoded to support interactivities linking. Every module
  234. //should have its own. They are called automatically from
  235. //assignment_decode_content_links_caller() function in each module
  236. //in the restore process
  237. function assignment_decode_content_links ($content,$restore) {
  238. global $CFG;
  239. $result = $content;
  240. //Link to the list of assignments
  241. $searchstring='/\$@(ASSIGNMENTINDEX)\*([0-9]+)@\$/';
  242. //We look for it
  243. preg_match_all($searchstring,$content,$foundset);
  244. //If found, then we are going to look for its new id (in backup tables)
  245. if ($foundset[0]) {
  246. //print_object($foundset); //Debug
  247. //Iterate over foundset[2]. They are the old_ids
  248. foreach($foundset[2] as $old_id) {
  249. //We get the needed variables here (course id)
  250. $rec = backup_getid($restore->backup_unique_code,"course",$old_id);
  251. //Personalize the searchstring
  252. $searchstring='/\$@(ASSIGNMENTINDEX)\*('.$old_id.')@\$/';
  253. //If it is a link to this course, update the link to its new location
  254. if($rec->new_id) {
  255. //Now replace it
  256. $result= preg_replace($searchstring,$CFG->wwwroot.'/mod/assignment/index.php?id='.$rec->new_id,$result);
  257. } else {
  258. //It's a foreign link so leave it as original
  259. $result= preg_replace($searchstring,$restore->original_wwwroot.'/mod/assignment/index.php?id='.$old_id,$result);
  260. }
  261. }
  262. }
  263. //Link to assignment view by moduleid
  264. $searchstring='/\$@(ASSIGNMENTVIEWBYID)\*([0-9]+)@\$/';
  265. //We look for it
  266. preg_match_all($searchstring,$result,$foundset);
  267. //If found, then we are going to look for its new id (in backup tables)
  268. if ($foundset[0]) {
  269. //print_object($foundset); //Debug
  270. //Iterate over foundset[2]. They are the old_ids
  271. foreach($foundset[2] as $old_id) {
  272. //We get the needed variables here (course_modules id)
  273. $rec = backup_getid($restore->backup_unique_code,"course_modules",$old_id);
  274. //Personalize the searchstring
  275. $searchstring='/\$@(ASSIGNMENTVIEWBYID)\*('.$old_id.')@\$/';
  276. //If it is a link to this course, update the link to its new location
  277. if($rec->new_id) {
  278. //Now replace it
  279. $result= preg_replace($searchstring,$CFG->wwwroot.'/mod/assignment/view.php?id='.$rec->new_id,$result);
  280. } else {
  281. //It's a foreign link so leave it as original
  282. $result= preg_replace($searchstring,$restore->original_wwwroot.'/mod/assignment/view.php?id='.$old_id,$result);
  283. }
  284. }
  285. }
  286. return $result;
  287. }
  288. //This function makes all the necessary calls to xxxx_decode_content_links()
  289. //function in each module, passing them the desired contents to be decoded
  290. //from backup format to destination site/course in order to mantain inter-activities
  291. //working in the backup/restore process. It's called from restore_decode_content_links()
  292. //function in restore process
  293. function assignment_decode_content_links_caller($restore) {
  294. global $CFG;
  295. $status = true;
  296. if ($assignments = get_records_sql ("SELECT a.id, a.description
  297. FROM {$CFG->prefix}assignment a
  298. WHERE a.course = $restore->course_id")) {
  299. //Iterate over each assignment->description
  300. $i = 0; //Counter to send some output to the browser to avoid timeouts
  301. foreach ($assignments as $assignment) {
  302. //Increment counter
  303. $i++;
  304. $content = $assignment->description;
  305. $result = restore_decode_content_links_worker($content,$restore);
  306. if ($result != $content) {
  307. //Update record
  308. $assignment->description = addslashes($result);
  309. $status = update_record("assignment",$assignment);
  310. if (debugging()) {
  311. if (!defined('RESTORE_SILENTLY')) {
  312. echo '<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />';
  313. }
  314. }
  315. }
  316. //Do some output
  317. if (($i+1) % 5 == 0) {
  318. if (!defined('RESTORE_SILENTLY')) {
  319. echo ".";
  320. if (($i+1) % 100 == 0) {
  321. echo "<br />";
  322. }
  323. }
  324. backup_flush(300);
  325. }
  326. }
  327. }
  328. return $status;
  329. }
  330. //This function converts texts in FORMAT_WIKI to FORMAT_MARKDOWN for
  331. //some texts in the module
  332. function assignment_restore_wiki2markdown ($restore) {
  333. global $CFG;
  334. $status = true;
  335. //Convert assignment->description
  336. if ($records = get_records_sql ("SELECT a.id, a.description, a.format
  337. FROM {$CFG->prefix}assignment a,
  338. {$CFG->prefix}backup_ids b
  339. WHERE a.course = $restore->course_id AND
  340. a.format = ".FORMAT_WIKI. " AND
  341. b.backup_code = $restore->backup_unique_code AND
  342. b.table_name = 'assignment' AND
  343. b.new_id = a.id")) {
  344. foreach ($records as $record) {
  345. //Rebuild wiki links
  346. $record->description = restore_decode_wiki_content($record->description, $restore);
  347. //Convert to Markdown
  348. $wtm = new WikiToMarkdown();
  349. $record->description = $wtm->convert($record->description, $restore->course_id);
  350. $record->format = FORMAT_MARKDOWN;
  351. $status = update_record('assignment', addslashes_object($record));
  352. //Do some output
  353. $i++;
  354. if (($i+1) % 1 == 0) {
  355. if (!defined('RESTORE_SILENTLY')) {
  356. echo ".";
  357. if (($i+1) % 20 == 0) {
  358. echo "<br />";
  359. }
  360. }
  361. backup_flush(300);
  362. }
  363. }
  364. }
  365. return $status;
  366. }
  367. //This function returns a log record with all the necessay transformations
  368. //done. It's used by restore_log_module() to restore modules log.
  369. function assignment_restore_logs($restore,$log) {
  370. $status = false;
  371. //Depending of the action, we recode different things
  372. switch ($log->action) {
  373. case "add":
  374. if ($log->cmid) {
  375. //Get the new_id of the module (to recode the info field)
  376. $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
  377. if ($mod) {
  378. $log->url = "view.php?id=".$log->cmid;
  379. $log->info = $mod->new_id;
  380. $status = true;
  381. }
  382. }
  383. break;
  384. case "update":
  385. if ($log->cmid) {
  386. //Get the new_id of the module (to recode the info field)
  387. $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
  388. if ($mod) {
  389. $log->url = "view.php?id=".$log->cmid;
  390. $log->info = $mod->new_id;
  391. $status = true;
  392. }
  393. }
  394. break;
  395. case "view":
  396. if ($log->cmid) {
  397. //Get the new_id of the module (to recode the info field)
  398. $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
  399. if ($mod) {
  400. $log->url = "view.php?id=".$log->cmid;
  401. $log->info = $mod->new_id;
  402. $status = true;
  403. }
  404. }
  405. break;
  406. case "view all":
  407. $log->url = "index.php?id=".$log->course;
  408. $status = true;
  409. break;
  410. case "upload":
  411. if ($log->cmid) {
  412. //Get the new_id of the module (to recode the info field)
  413. $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
  414. if ($mod) {
  415. $log->url = "view.php?a=".$mod->new_id;
  416. $log->info = $mod->new_id;
  417. $status = true;
  418. }
  419. }
  420. break;
  421. case "view submission":
  422. if ($log->cmid) {
  423. //Get the new_id of the module (to recode the info field)
  424. $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
  425. if ($mod) {
  426. $log->url = "submissions.php?id=".$mod->new_id;
  427. $log->info = $mod->new_id;
  428. $status = true;
  429. }
  430. }
  431. break;
  432. case "update grades":
  433. if ($log->cmid) {
  434. //Extract the assignment id from the url field
  435. $assid = substr(strrchr($log->url,"="),1);
  436. //Get the new_id of the module (to recode the info field)
  437. $mod = backup_getid($restore->backup_unique_code,$log->module,$assid);
  438. if ($mod) {
  439. $log->url = "submissions.php?id=".$mod->new_id;
  440. $status = true;
  441. }
  442. }
  443. break;
  444. default:
  445. if (!defined('RESTORE_SILENTLY')) {
  446. echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />"; //Debug
  447. }
  448. break;
  449. }
  450. if ($status) {
  451. $status = $log;
  452. }
  453. return $status;
  454. }
  455. ?>