CourseRestorer.class.php 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. <?php // $Id: CourseRestorer.class.php 22200 2009-07-17 19:47:58Z iflorespaz $
  2. /*
  3. ==============================================================================
  4. Dokeos - elearning and course management software
  5. Copyright (c) 2008 Dokeos SPRL
  6. Copyright (c) 2003 Ghent University (UGent)
  7. Copyright (c) 2001 Universite catholique de Louvain (UCL)
  8. Copyright (c) Bart Mollet (bart.mollet@hogent.be)
  9. For a full list of contributors, see "credits.txt".
  10. The full license can be read in "license.txt".
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15. See the GNU General Public License for more details.
  16. Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
  17. Mail: info@dokeos.com
  18. ==============================================================================
  19. */
  20. require_once ('Course.class.php');
  21. require_once ('Event.class.php');
  22. require_once ('Link.class.php');
  23. require_once ('ToolIntro.class.php');
  24. require_once ('LinkCategory.class.php');
  25. require_once ('ForumCategory.class.php');
  26. require_once ('Forum.class.php');
  27. require_once ('ForumTopic.class.php');
  28. require_once ('ForumPost.class.php');
  29. require_once ('CourseDescription.class.php');
  30. require_once ('Learnpath.class.php');
  31. require_once ('Survey.class.php');
  32. require_once ('SurveyQuestion.class.php');
  33. require_once ('mkdirr.php');
  34. require_once ('rmdirr.php');
  35. require_once ('Glossary.class.php');
  36. include_once(api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php');
  37. define('FILE_SKIP', 1);
  38. define('FILE_RENAME', 2);
  39. define('FILE_OVERWRITE', 3);
  40. /**
  41. * Class to restore items from a course object to a Dokeos-course
  42. * @author Bart Mollet <bart.mollet@hogent.be>
  43. * @package dokeos.backup
  44. */
  45. class CourseRestorer
  46. {
  47. /**
  48. * The course-object
  49. */
  50. var $course;
  51. /**
  52. * What to do with files with same name (FILE_SKIP, FILE_RENAME or
  53. * FILE_OVERWRITE)
  54. */
  55. var $file_option;
  56. /**
  57. * Create a new CourseRestorer
  58. */
  59. function CourseRestorer($course)
  60. {
  61. $this->course = $course;
  62. $this->file_option = FILE_RENAME;
  63. }
  64. /**
  65. * Set the file-option
  66. * @param constant $options What to do with files with same name (FILE_SKIP,
  67. * FILE_RENAME or FILE_OVERWRITE)
  68. */
  69. function set_file_option($option)
  70. {
  71. $this->file_option = $option;
  72. }
  73. /**
  74. * Restore a course.
  75. * @param string $destination_course_code The code of the Dokeos-course in
  76. * which the resources should be stored. Default: Current Dokeos-course.
  77. */
  78. function restore($destination_course_code = '')
  79. {
  80. if ($destination_course_code == '') {
  81. $course_info = api_get_course_info();
  82. $this->course->destination_db = $course_info['dbName'];
  83. $this->course->destination_path = $course_info['path'];
  84. } else {
  85. $course_info = Database :: get_course_info($destination_course_code);
  86. $this->course->destination_db = $course_info['database'];
  87. $this->course->destination_path = $course_info['directory'];
  88. }
  89. // platform encoding
  90. $course_charset = $this->course->encoding;
  91. $this->restore_links();
  92. $this->restore_tool_intro();
  93. $this->restore_events();
  94. $this->restore_announcements();
  95. $this->restore_documents();
  96. $this->restore_scorm_documents();
  97. $this->restore_course_descriptions();
  98. // Enabled by Ivan Tcholakov, 30-AUG-2009.
  99. ////$this->restore_forums();
  100. $this->restore_forums();
  101. //
  102. $this->restore_quizzes(); // after restore_documents! (for correct import of sound/video)
  103. $this->restore_learnpaths();
  104. $this->restore_surveys();
  105. $this->restore_student_publication();
  106. $this->restore_glossary();
  107. // Restore the item properties
  108. $table = Database :: get_course_table(TABLE_ITEM_PROPERTY, $this->course->destination_db);
  109. foreach ($this->course->resources as $type => $resources) {
  110. if (is_array($resources)) {
  111. foreach ($resources as $id => $resource) {
  112. foreach ($resource->item_properties as $property)
  113. {
  114. // First check if there isn't allready a record for this resource
  115. $sql = "SELECT * FROM $table WHERE tool = '".$property['tool']."' AND ref = '".$resource->destination_id."'";
  116. $res = api_sql_query($sql,__FILE__,__LINE__);
  117. if( Database::num_rows($res) == 0) {
  118. // The to_group_id and to_user_id are set to default values as users/groups possibly not exist in the target course
  119. $sql = "INSERT INTO $table SET
  120. tool = '".Database::escape_string($property['tool'])."',
  121. insert_user_id = '".Database::escape_string($property['insert_user_id'])."',
  122. insert_date = '".Database::escape_string($property['insert_date'])."',
  123. lastedit_date = '".Database::escape_string($property['lastedit_date'])."',
  124. ref = '".Database::escape_string($resource->destination_id)."',
  125. lastedit_type = '".Database::escape_string($property['lastedit_type'])."',
  126. lastedit_user_id = '".Database::escape_string($property['lastedit_user_id'])."',
  127. visibility = '".Database::escape_string($property['visibility'])."',
  128. start_visible = '".Database::escape_string($property['start_visible'])."',
  129. end_visible = '".Database::escape_string($property['end_visible'])."',
  130. to_user_id = '".Database::escape_string($property['to_user_id'])."',
  131. to_group_id = '0'";
  132. ;
  133. api_sql_query($sql, __FILE__, __LINE__);
  134. }
  135. }
  136. }
  137. }
  138. }
  139. // Restore the linked-resources
  140. $table = Database :: get_course_table(TABLE_LINKED_RESOURCES, $this->course->destination_db);
  141. foreach ($this->course->resources as $type => $resources)
  142. {
  143. if (is_array($resources))
  144. foreach ($resources as $id => $resource)
  145. {
  146. $linked_resources = $resource->get_linked_resources();
  147. foreach ($linked_resources as $to_type => $to_ids)
  148. {
  149. foreach ($to_ids as $index => $to_id)
  150. {
  151. $to_resource = $this->course->resources[$to_type][$to_id];
  152. $sql = "INSERT INTO ".$table." SET source_type = '".$type."', source_id = '".$resource->destination_id."', resource_type='".$to_type."', resource_id='".$to_resource->destination_id."' ";
  153. api_sql_query($sql, __FILE__, __LINE__);
  154. }
  155. }
  156. }
  157. }
  158. }
  159. /**
  160. * Restore documents
  161. */
  162. function restore_documents()
  163. {
  164. if ($this->course->has_resources(RESOURCE_DOCUMENT)) {
  165. $table = Database :: get_course_table(TABLE_DOCUMENT, $this->course->destination_db);
  166. $resources = $this->course->resources;
  167. $destination_course['dbName']= $this->course->destination_db;
  168. /* echo '<pre>'; echo $this->course->backup_path; echo '<br>'; */
  169. foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) {
  170. $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
  171. $perm = api_get_setting('permissions_for_new_directories');
  172. $perm = octdec(!empty($perm)?$perm:0770);
  173. $dirs = explode('/', dirname($document->path));
  174. if (count($dirs)==1) {
  175. if ($this->file_type==FOLDER) {
  176. $new = substr($document->path, 8);
  177. $created_dir = create_unexisting_directory($destination_course,api_get_user_id(),0, 0 ,$path.'document',$new,basename($new));
  178. }
  179. } else {
  180. $my_temp = '';
  181. for ($i=1; $i<=count($dirs); $i++) {
  182. $my_temp .= $dirs[$i];
  183. if (!is_dir($path.'document/'.$my_temp)) {
  184. $sql = "SELECT id FROM ".$table." WHERE path='/".Database::escape_string($my_temp)."'";
  185. //echo '<br>';
  186. $res = api_sql_query($sql, __FILE__, __LINE__);
  187. $num_result = Database::num_rows($res);
  188. if ($num_result==0) {
  189. $created_dir = create_unexisting_directory($destination_course,api_get_user_id(),0, 0 ,$path.'document','/'.$my_temp,basename($my_temp));
  190. }
  191. }
  192. $my_temp .= '/';
  193. }
  194. }
  195. /*
  196. echo '<br>';
  197. echo '------------------------';
  198. echo '<br>';
  199. echo '$doculent:';echo '<br>';
  200. echo print_r($document); echo '<br>';
  201. echo 'documlent->path'.$path.$document->path;echo '<br>';
  202. echo 'file option:'.$this->file_option; echo '<br>';
  203. echo 'filetype:'.$document->file_type ;
  204. echo '<br>';
  205. */
  206. if ($document->file_type == DOCUMENT) {
  207. if (file_exists($path.$document->path)) {
  208. switch ($this->file_option) {
  209. case FILE_OVERWRITE :
  210. $this->course->backup_path.'/'.$document->path;
  211. copy($this->course->backup_path.'/'.$document->path, $path.$document->path);
  212. $sql = "SELECT id FROM ".$table." WHERE path='/".substr($document->path, 9)."'";
  213. $res = api_sql_query($sql, __FILE__, __LINE__);
  214. $obj = Database::fetch_object($res);
  215. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
  216. $sql = "UPDATE ".$table." SET comment = '".Database::escape_string($document->comment)."', title='".Database::escape_string($document->title)."', size='".$document->size."' WHERE id = '".$obj->id."'";
  217. api_sql_query($sql, __FILE__, __LINE__);
  218. break;
  219. case FILE_SKIP :
  220. $sql = "SELECT id FROM ".$table." WHERE path='/".Database::escape_string(substr($document->path, 9))."'";
  221. $res = api_sql_query($sql, __FILE__, __LINE__);
  222. $obj = Database::fetch_object($res);
  223. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
  224. break;
  225. case FILE_RENAME :
  226. $i = 1;
  227. $ext = explode('.', basename($document->path));
  228. if (count($ext) > 1) {
  229. $ext = array_pop($ext);
  230. $file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
  231. $ext = '.'.$ext;
  232. } else {
  233. $ext = '';
  234. $file_name_no_ext = $document->path;
  235. }
  236. $new_file_name = $file_name_no_ext.'_'.$i.$ext;
  237. $file_exists = file_exists($path.$new_file_name);
  238. while ($file_exists) {
  239. $i ++;
  240. $new_file_name = $file_name_no_ext.'_'.$i.$ext;
  241. $file_exists = file_exists($path.$new_file_name);
  242. }
  243. copy($this->course->backup_path.'/'.$document->path, $path.$new_file_name);
  244. $sql = "INSERT INTO ".$table." SET path = '/".Database::escape_string(substr($new_file_name, 9))."', comment = '".Database::escape_string($document->comment)."', title = '".Database::escape_string($document->title)."' ,filetype='".$document->file_type."', size= '".$document->size."'";
  245. api_sql_query($sql, __FILE__, __LINE__);
  246. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = Database::get_last_insert_id();
  247. //also insert into item_property
  248. /*
  249. api_item_property_update(
  250. array('dbName'=>$this->course->destination_db,
  251. TOOL_DOCUMENT,
  252. $this->course->resource[RESOURCE_DOCUMENT][$id]->destination_id,
  253. 'DocumentAdded',
  254. );
  255. */
  256. break;
  257. } // end switch
  258. } // end if file exists
  259. else
  260. {
  261. //make sure the source file actually exists
  262. //echo $this->course->backup_path.'/'.$document->path;
  263. if(is_file($this->course->backup_path.'/'.$document->path) && is_readable($this->course->backup_path.'/'.$document->path) && is_dir(dirname($path.$document->path)) && is_writeable(dirname($path.$document->path)))
  264. {
  265. copy($this->course->backup_path.'/'.$document->path, $path.$document->path);
  266. $sql = "INSERT INTO ".$table." SET path = '/".substr($document->path, 9)."', comment = '".Database::escape_string($document->comment)."', title = '".Database::escape_string($document->title)."' ,filetype='".$document->file_type."', size= '".$document->size."'";
  267. api_sql_query($sql, __FILE__, __LINE__);
  268. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = Database::get_last_insert_id();
  269. }
  270. else
  271. {
  272. if(is_file($this->course->backup_path.'/'.$document->path) && is_readable($this->course->backup_path.'/'.$document->path))
  273. {
  274. error_log('Course copy generated an ignoreable error while trying to copy '.$this->course->backup_path.'/'.$document->path.': file not found');
  275. }
  276. if(!is_dir(dirname($path.$document->path)))
  277. {
  278. error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not found');
  279. }
  280. if(!is_writeable(dirname($path.$document->path)))
  281. {
  282. error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not writeable');
  283. }
  284. }
  285. } // end file doesn't exist
  286. }
  287. else
  288. {
  289. /*$sql = "SELECT id FROM ".$table." WHERE path = '/".Database::escape_string(substr($document->path, 9))."'";
  290. $res = api_sql_query($sql,__FILE__,__LINE__);
  291. if( Database::num_rows($res)> 0)
  292. {
  293. $obj = Database::fetch_object($res);
  294. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
  295. }
  296. else
  297. {
  298. $sql = "INSERT INTO ".$table." SET path = '/".Database::escape_string(substr($document->path, 9))."', comment = '".Database::escape_string($document->comment)."', title = '".Database::escape_string($document->title)."' ,filetype='".$document->file_type."', size= '".$document->size."'";
  299. api_sql_query($sql, __FILE__, __LINE__);
  300. $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = Database::get_last_insert_id();
  301. }*/
  302. } // end folder
  303. } // end for each
  304. }
  305. }
  306. /**
  307. * Restore scorm documents
  308. * TODO @TODO check that the restore function with renaming doesn't break the scorm structure!
  309. */
  310. function restore_scorm_documents()
  311. {
  312. if ($this->course->has_resources(RESOURCE_SCORM))
  313. {
  314. $resources = $this->course->resources;
  315. foreach ($resources[RESOURCE_SCORM] as $id => $document)
  316. {
  317. $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
  318. $perm = api_get_setting('permissions_for_new_directories');
  319. $perm = octdec(!empty($perm)?$perm:'0770');
  320. mkdirr(dirname($path.$document->path),$perm);
  321. if (file_exists($path.$document->path))
  322. {
  323. switch ($this->file_option)
  324. {
  325. case FILE_OVERWRITE :
  326. rmdirr($path.$document->path);
  327. copyDirTo($this->course->backup_path.'/'.$document->path, $path.dirname($document->path), false);
  328. break;
  329. case FILE_SKIP :
  330. break;
  331. case FILE_RENAME :
  332. $i = 1;
  333. $ext = explode('.', basename($document->path));
  334. if (count($ext) > 1)
  335. {
  336. $ext = array_pop($ext);
  337. $file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
  338. $ext = '.'.$ext;
  339. }
  340. else
  341. {
  342. $ext = '';
  343. $file_name_no_ext = $document->path;
  344. }
  345. $new_file_name = $file_name_no_ext.'_'.$i.$ext;
  346. $file_exists = file_exists($path.$new_file_name);
  347. while ($file_exists)
  348. {
  349. $i ++;
  350. $new_file_name = $file_name_no_ext.'_'.$i.$ext;
  351. $file_exists = file_exists($path.$new_file_name);
  352. }
  353. rename($this->course->backup_path.'/'.$document->path,$this->course->backup_path.'/'.$new_file_name);
  354. copyDirTo($this->course->backup_path.'/'.$new_file_name, $path.dirname($new_file_name), false);
  355. rename($this->course->backup_path.'/'.$new_file_name,$this->course->backup_path.'/'.$document->path);
  356. break;
  357. } // end switch
  358. } // end if file exists
  359. else
  360. {
  361. copyDirTo($this->course->backup_path.'/'.$document->path, $path.dirname($document->path), false);
  362. }
  363. } // end for each
  364. }
  365. }
  366. /**
  367. * Restore forums
  368. */
  369. function restore_forums()
  370. {
  371. if ($this->course->has_resources(RESOURCE_FORUM))
  372. {
  373. $table_forum = Database :: get_course_table(TABLE_FORUM, $this->course->destination_db);
  374. $table_topic = Database :: get_course_table(TABLE_FORUM_THREAD, $this->course->destination_db);
  375. $table_post = Database :: get_course_table(TABLE_FORUM_POST, $this->course->destination_db);
  376. $resources = $this->course->resources;
  377. foreach ($resources[RESOURCE_FORUM] as $id => $forum)
  378. {
  379. $cat_id = $this->restore_forum_category($forum->category_id);
  380. $sql = "INSERT INTO ".$table_forum.
  381. " SET forum_title = '".Database::escape_string($forum->title).
  382. "', forum_comment = '".Database::escape_string($forum->description).
  383. "', forum_category = ".(int)Database::escape_string($cat_id).
  384. ", forum_last_post = ".(int)Database::escape_string($forum->last_post).
  385. ", forum_threads = ".(int)Database::escape_string($forum->topics).
  386. ", forum_posts = ".(int)Database::escape_string($forum->posts).
  387. ", allow_anonymous = ".(int)Database::escape_string($forum->allow_anonymous).
  388. ", allow_edit = ".(int)Database::escape_string($forum->allow_edit).
  389. ", approval_direct_post = '".Database::escape_string($forum->approval_direct_post).
  390. "', allow_attachments = ".(int)Database::escape_string($forum->allow_attachments).
  391. ", allow_new_threads = ".(int)Database::escape_string($forum->allow_new_topics).
  392. ", default_view = '".Database::escape_string($forum->default_view).
  393. "', forum_of_group = '".Database::escape_string($forum->of_group).
  394. "', forum_group_public_private = '".Database::escape_string($forum->group_public_private).
  395. "', forum_order = ".(int)Database::escape_string($forum->order).
  396. ", locked = ".(int)Database::escape_string($forum->locked).
  397. ", session_id = ".(int)Database::escape_string($forum->session_id).
  398. ", forum_image = '".Database::escape_string($forum->image)."'";
  399. api_sql_query($sql, __FILE__, __LINE__);
  400. $new_id = Database::get_last_insert_id();
  401. $this->course->resources[RESOURCE_FORUM][$id]->destination_id = $new_id;
  402. $forum_topics = 0;
  403. if (is_array($this->course->resources[RESOURCE_FORUMTOPIC]))
  404. {
  405. foreach ($this->course->resources[RESOURCE_FORUMTOPIC] as $topic_id => $topic)
  406. {
  407. if ($topic->forum_id == $id)
  408. {
  409. $this->restore_topic($topic_id, $new_id);
  410. $forum_topics ++;
  411. }
  412. }
  413. }
  414. if ($forum_topics > 0)
  415. {
  416. $last_post = $this->course->resources[RESOURCE_FORUMPOST][$forum->last_post];
  417. $sql = "UPDATE ".$table_forum." SET forum_threads = ".$forum_topics.", forum_last_post = ".(int)$last_post->destination_id." WHERE forum_id = ".(int)$new_id;
  418. api_sql_query($sql, __FILE__, __LINE__);
  419. }
  420. }
  421. }
  422. }
  423. /**
  424. * Restore forum-categories
  425. */
  426. function restore_forum_category($id)
  427. {
  428. $forum_cat_table = Database :: get_course_table(TABLE_FORUM_CATEGORY, $this->course->destination_db);
  429. $resources = $this->course->resources;
  430. $forum_cat = $resources[RESOURCE_FORUMCATEGORY][$id];
  431. if (!$forum_cat->is_restored())
  432. {
  433. $title = $forum_cat->title;
  434. if (!preg_match('/.*\((.+)\)$/', $title, $matches)) // This is for avoiding repetitive adding of training code after several backup/restore cycles.
  435. {
  436. if ($matches[1] != $this->course->code)
  437. {
  438. $title = $title.' ('.$this->course->code.')';
  439. }
  440. }
  441. $sql = "INSERT INTO ".$forum_cat_table.
  442. " SET cat_title = '".Database::escape_string($title).
  443. "', cat_comment = '".Database::escape_string($forum_cat->description).
  444. "', cat_order = ".(int)Database::escape_string($forum_cat->order).
  445. ", locked = ".(int)Database::escape_string($forum_cat->locked).
  446. ", session_id = ".(int)Database::escape_string($forum_cat->session_id);
  447. api_sql_query($sql, __FILE__, __LINE__);
  448. $new_id = Database::get_last_insert_id();
  449. $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id = $new_id;
  450. return $new_id;
  451. }
  452. return $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id;
  453. }
  454. /**
  455. * Restore a forum-topic
  456. */
  457. function restore_topic($id, $forum_id)
  458. {
  459. $table = Database :: get_course_table(TABLE_FORUM_THREAD, $this->course->destination_db);
  460. $resources = $this->course->resources;
  461. $topic = $resources[RESOURCE_FORUMTOPIC][$id];
  462. $sql = "INSERT INTO ".$table.
  463. " SET thread_title = '".Database::escape_string($topic->title).
  464. "', forum_id = ".(int)Database::escape_string($forum_id).
  465. ", thread_date = '".Database::escape_string($topic->time).
  466. "', thread_poster_id = ".(int)Database::escape_string($topic->topic_poster_id).
  467. ", thread_poster_name = '".Database::escape_string($topic->topic_poster_name).
  468. "', thread_views = ".(int)Database::escape_string($topic->views).
  469. ", thread_sticky = ".(int)Database::escape_string($topic->sticky).
  470. ", locked = ".(int)Database::escape_string($topic->locked).
  471. ", thread_close_date = '".Database::escape_string($topic->time_closed).
  472. "', thread_weight = ".(float)Database::escape_string($topic->weight).
  473. ", thread_title_qualify = '".Database::escape_string($topic->title_qualify).
  474. "', thread_qualify_max = ".(float)Database::escape_string($topic->qualify_max);
  475. api_sql_query($sql, __FILE__, __LINE__);
  476. $new_id = Database::get_last_insert_id();
  477. $this->course->resources[RESOURCE_FORUMTOPIC][$id]->destination_id = $new_id;
  478. $topic_replies = -1;
  479. foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post)
  480. {
  481. if ($post->topic_id == $id)
  482. {
  483. $topic_replies ++;
  484. $this->restore_post($post_id, $new_id, $forum_id);
  485. }
  486. }
  487. $last_post = $this->course->resources[RESOURCE_FORUMPOST][$topic->last_post];
  488. if (is_object($last_post))
  489. {
  490. $sql = "UPDATE ".$table." SET thread_last_post = ".(int)$last_post->destination_id;
  491. api_sql_query($sql, __FILE__, __LINE__);
  492. }
  493. if ($topic_replies >= 0)
  494. {
  495. $sql = "UPDATE ".$table." SET thread_replies = ".$topic_replies;
  496. api_sql_query($sql, __FILE__, __LINE__);
  497. }
  498. return $new_id;
  499. }
  500. /**
  501. * Restore a forum-post
  502. * @TODO Restore tree-structure of posts. For example: attachments to posts.
  503. */
  504. function restore_post($id, $topic_id, $forum_id)
  505. {
  506. $table_post = Database :: get_course_table(TABLE_FORUM_POST, $this->course->destination_db);
  507. $resources = $this->course->resources;
  508. $post = $resources[RESOURCE_FORUMPOST][$id];
  509. $sql = "INSERT INTO ".$table_post.
  510. " SET post_title = '".Database::escape_string($post->title).
  511. "', post_text = '".Database::escape_string($post->text).
  512. "', thread_id = ".(int)Database::escape_string($topic_id).
  513. ", post_date = '".Database::escape_string($post->post_time).
  514. "', forum_id = ".(int)Database::escape_string($forum_id).
  515. ", poster_id = ".(int)Database::escape_string($post->poster_id).
  516. ", poster_name = '".Database::escape_string($post->poster_name).
  517. "', post_notification = ".(int)Database::escape_string($post->topic_notify).
  518. ", post_parent_id = ".(int)Database::escape_string($post->parent_post_id).
  519. ", visible = ".(int)Database::escape_string($post->visible);
  520. api_sql_query($sql, __FILE__, __LINE__);
  521. $new_id = Database::get_last_insert_id();
  522. $this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
  523. return $new_id;
  524. }
  525. /**
  526. * Restore links
  527. */
  528. function restore_links()
  529. {
  530. if ($this->course->has_resources(RESOURCE_LINK))
  531. {
  532. $link_table = Database :: get_course_table(TABLE_LINK, $this->course->destination_db);
  533. $resources = $this->course->resources;
  534. foreach ($resources[RESOURCE_LINK] as $id => $link)
  535. {
  536. $cat_id = $this->restore_link_category($link->category_id);
  537. $sql = "SELECT MAX(display_order) FROM $link_table WHERE category_id='" . Database::escape_string($cat_id). "'";
  538. $result = api_sql_query($sql, __FILE__, __LINE__);
  539. list($max_order) = Database::fetch_array($result);
  540. $sql = "INSERT INTO ".$link_table." SET url = '".Database::escape_string($link->url)."', title = '".Database::escape_string($link->title)."', description = '".Database::escape_string($link->description)."', category_id='".$cat_id."', on_homepage = '".$link->on_homepage."', display_order='".($max_order+1)."'";
  541. api_sql_query($sql, __FILE__, __LINE__);
  542. $this->course->resources[RESOURCE_LINK][$id]->destination_id = Database::get_last_insert_id();
  543. }
  544. }
  545. }
  546. /**
  547. * Restore tool intro
  548. */
  549. function restore_tool_intro()
  550. {
  551. if ($this->course->has_resources(RESOURCE_TOOL_INTRO))
  552. {
  553. $tool_intro_table = Database :: get_course_table(TABLE_TOOL_INTRO, $this->course->destination_db);
  554. $resources = $this->course->resources;
  555. foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro)
  556. {
  557. $sql = "DELETE FROM ".$tool_intro_table." WHERE id='".Database::escape_string($tool_intro->id)."'";
  558. api_sql_query($sql, __FILE__, __LINE__);
  559. $sql = "INSERT INTO ".$tool_intro_table." SET id='".Database::escape_string($tool_intro->id)."', intro_text = '".Database::escape_string($tool_intro->intro_text)."'";
  560. api_sql_query($sql, __FILE__, __LINE__);
  561. $this->course->resources[RESOURCE_TOOL_INTRO][$id]->destination_id = Database::get_last_insert_id();
  562. }
  563. }
  564. }
  565. /**
  566. * Restore a link-category
  567. */
  568. function restore_link_category($id)
  569. {
  570. if ($id == 0)
  571. return 0;
  572. $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY, $this->course->destination_db);
  573. $resources = $this->course->resources;
  574. $link_cat = $resources[RESOURCE_LINKCATEGORY][$id];
  575. if (is_object($link_cat) && !$link_cat->is_restored())
  576. {
  577. $sql = "SELECT MAX(display_order) FROM $link_cat_table";
  578. $result=api_sql_query($sql,__FILE__,__LINE__);
  579. list($orderMax)=Database::fetch_array($result,'NUM');
  580. $display_order=$orderMax+1;
  581. $sql = "INSERT INTO ".$link_cat_table." SET category_title = '".Database::escape_string($link_cat->title)."', description='".Database::escape_string($link_cat->description)."', display_order='".$display_order."' ";
  582. api_sql_query($sql, __FILE__, __LINE__);
  583. $new_id = Database::get_last_insert_id();
  584. $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id = $new_id;
  585. return $new_id;
  586. }
  587. return $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id;
  588. }
  589. /**
  590. * Restore events
  591. */
  592. function restore_events()
  593. {
  594. if ($this->course->has_resources(RESOURCE_EVENT))
  595. {
  596. $table = Database :: get_course_table(TABLE_AGENDA, $this->course->destination_db);
  597. $resources = $this->course->resources;
  598. foreach ($resources[RESOURCE_EVENT] as $id => $event)
  599. {
  600. $sql = "INSERT INTO ".$table." SET title = '".Database::escape_string($event->title)."', content = '".Database::escape_string($event->content)."', start_date = '".$event->start_date."', end_date = '".$event->end_date."'";
  601. api_sql_query($sql, __FILE__, __LINE__);
  602. $this->course->resources[RESOURCE_EVENT][$id]->destination_id = Database::get_last_insert_id();
  603. }
  604. }
  605. }
  606. /**
  607. * Restore course-description
  608. */
  609. function restore_course_descriptions()
  610. {
  611. if ($this->course->has_resources(RESOURCE_COURSEDESCRIPTION))
  612. {
  613. $table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION, $this->course->destination_db);
  614. $resources = $this->course->resources;
  615. foreach ($resources[RESOURCE_COURSEDESCRIPTION] as $id => $cd)
  616. {
  617. if (isset($_POST['destination_course'])) {
  618. $course_destination=Security::remove_XSS($_POST['destination_course']);
  619. $course_destination=api_get_course_info($course_destination);
  620. $course_destination=$course_destination['path'];
  621. } else {
  622. $course_destination=$this->course->destination_path;
  623. }
  624. $course_info=api_get_course_info(api_get_course_id());
  625. $search='../courses/'.$course_info['path'].'/document';
  626. $replace_search_by='../courses/'.$course_destination.'/document';
  627. $description_content=str_replace($search,$replace_search_by,$cd->content);
  628. $sql = "INSERT INTO ".$table." SET title = '".Database::escape_string($cd->title)."', content = '".Database::escape_string($description_content)."'";
  629. api_sql_query($sql, __FILE__, __LINE__);
  630. $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = Database::get_last_insert_id();
  631. }
  632. }
  633. }
  634. /**
  635. * Restore announcements
  636. */
  637. function restore_announcements()
  638. {
  639. if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT))
  640. {
  641. $table = Database :: get_course_table(TABLE_ANNOUNCEMENT, $this->course->destination_db);
  642. $resources = $this->course->resources;
  643. foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement)
  644. {
  645. $sql = "INSERT INTO ".$table." " .
  646. "SET title = '".Database::escape_string($announcement->title)."'," .
  647. "content = '".Database::escape_string($announcement->content)."', " .
  648. "end_date = '".$announcement->date."', " .
  649. "display_order = '".$announcement->display_order."', " .
  650. "email_sent = '".$announcement->email_sent."'";
  651. api_sql_query($sql, __FILE__, __LINE__);
  652. $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = Database::get_last_insert_id();
  653. }
  654. }
  655. }
  656. /**
  657. * Restore Quiz
  658. */
  659. function restore_quizzes()
  660. {
  661. if ($this->course->has_resources(RESOURCE_QUIZ))
  662. {
  663. $table_qui = Database :: get_course_table(TABLE_QUIZ_TEST, $this->course->destination_db);
  664. $table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course->destination_db);
  665. $table_doc = Database :: get_course_table(TABLE_DOCUMENT, $this->course->destination_db);
  666. $resources = $this->course->resources;
  667. foreach ($resources[RESOURCE_QUIZ] as $id => $quiz)
  668. {
  669. $doc = '';
  670. if (strlen($quiz->media) > 0)
  671. {
  672. if ($this->course->resources[RESOURCE_DOCUMENT][$quiz->media]->is_restored())
  673. {
  674. $sql = "SELECT path FROM ".$table_doc." WHERE id = ".$resources[RESOURCE_DOCUMENT][$quiz->media]->destination_id;
  675. $doc = api_sql_query($sql, __FILE__, __LINE__);
  676. $doc = Database::fetch_object($doc);
  677. $doc = str_replace('/audio/', '', $doc->path);
  678. }
  679. }
  680. $sql = "INSERT INTO ".$table_qui." SET title = '".Database::escape_string($quiz->title)."', description = '".Database::escape_string($quiz->description)."', type = '".$quiz->quiz_type."', random = '".$quiz->random."', active = '".$quiz->active."', sound = '".Database::escape_string($doc)."', max_attempt = '".$quiz->attempts."' ";
  681. api_sql_query($sql, __FILE__, __LINE__);
  682. $new_id = Database::get_last_insert_id();
  683. $this->course->resources[RESOURCE_QUIZ][$id]->destination_id = $new_id;
  684. foreach ($quiz->question_ids as $index => $question_id)
  685. {
  686. $qid = $this->restore_quiz_question($question_id);
  687. $sql = "INSERT IGNORE INTO ".$table_rel." SET question_id = ".$qid.", exercice_id = ".$new_id."";
  688. api_sql_query($sql, __FILE__, __LINE__);
  689. }
  690. }
  691. }
  692. }
  693. /**
  694. * Restore quiz-questions
  695. */
  696. function restore_quiz_question($id)
  697. {
  698. $resources = $this->course->resources;
  699. $question = $resources[RESOURCE_QUIZQUESTION][$id];
  700. $new_id=0;
  701. if(is_object($question))
  702. {
  703. if ($question->is_restored())
  704. {
  705. return $question->destination_id;
  706. }
  707. $table_que = Database :: get_course_table(TABLE_QUIZ_QUESTION, $this->course->destination_db);
  708. $table_ans = Database :: get_course_table(TABLE_QUIZ_ANSWER, $this->course->destination_db);
  709. $sql = "INSERT INTO ".$table_que." SET question = '".addslashes($question->question)."', description = '".addslashes($question->description)."', ponderation = '".addslashes($question->ponderation)."', position = '".addslashes($question->position)."', type='".addslashes($question->quiz_type)."', picture='".addslashes($question->picture)."', level='".addslashes($question->level)."'";
  710. api_sql_query($sql, __FILE__, __LINE__);
  711. $new_id = Database::get_last_insert_id();
  712. foreach ($question->answers as $index => $answer)
  713. {
  714. $sql = "INSERT INTO ".$table_ans." SET id= '". ($index +1)."',question_id = '".$new_id."', answer = '".Database::escape_string($answer['answer'])."', correct = '".$answer['correct']."', comment = '".Database::escape_string($answer['comment'])."', ponderation='".$answer['ponderation']."', position = '".$answer['position']."', hotspot_coordinates = '".$answer['hotspot_coordinates']."', hotspot_type = '".$answer['hotspot_type']."'";
  715. api_sql_query($sql, __FILE__, __LINE__);
  716. }
  717. $this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
  718. }
  719. return $new_id;
  720. }
  721. /**
  722. * Restore surveys
  723. */
  724. function restore_surveys()
  725. {
  726. if ($this->course->has_resources(RESOURCE_SURVEY))
  727. {
  728. $table_sur = Database :: get_course_table(TABLE_SURVEY, $this->course->destination_db);
  729. $table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION, $this->course->destination_db);
  730. $table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION, $this->course->destination_db);
  731. $resources = $this->course->resources;
  732. foreach ($resources[RESOURCE_SURVEY] as $id => $survey)
  733. {
  734. $sql_check = 'SELECT survey_id FROM '.$table_sur.'
  735. WHERE code = "'.Database::escape_string($survey->code).'"
  736. AND lang="'.Database::escape_string($survey->lang).'"
  737. ';
  738. $result_check = api_sql_query($sql_check, __FILE__, __LINE__);
  739. $doc = '';
  740. $sql = "INSERT INTO ".$table_sur." " .
  741. "SET code = '".Database::escape_string($survey->code)."', " .
  742. "title = '".Database::escape_string($survey->title)."', " .
  743. "subtitle = '".Database::escape_string($survey->subtitle)."', " .
  744. "author = '".Database::escape_string($survey->author)."', " .
  745. "lang = '".Database::escape_string($survey->lang)."', " .
  746. "avail_from = '".Database::escape_string($survey->avail_from)."', " .
  747. "avail_till = '".Database::escape_string($survey->avail_till)."', " .
  748. "is_shared = '".Database::escape_string($survey->is_shared)."', " .
  749. "template = '".Database::escape_string($survey->template)."', " .
  750. "intro = '".Database::escape_string($survey->intro)."', " .
  751. "surveythanks = '".Database::escape_string($survey->surveythanks)."', " .
  752. "creation_date = '".Database::escape_string($survey->creation_date)."', " .
  753. "invited = '0', " .
  754. "answered = '0', " .
  755. "invite_mail = '".Database::escape_string($survey->invite_mail)."', " .
  756. "reminder_mail = '".Database::escape_string($survey->reminder_mail)."'";
  757. //An existing survey exists with the same code and the same language
  758. if(Database::num_rows($result_check) == 1)
  759. {
  760. switch ($this->file_option) {
  761. case FILE_SKIP:
  762. //Do nothing
  763. break;
  764. case FILE_RENAME:
  765. $survey_code = $survey->code.'_';
  766. $i=1;
  767. $temp_survey_code = $survey_code.$i;
  768. while (!$this->is_survey_code_available($temp_survey_code))
  769. {
  770. $temp_survey_code = $survey_code.++$i;
  771. }
  772. $survey_code = $temp_survey_code;
  773. $sql = "INSERT INTO ".$table_sur." " .
  774. "SET code = '".Database::escape_string($survey_code)."', " .
  775. "title = '".Database::escape_string($survey->title)."', " .
  776. "subtitle = '".Database::escape_string($survey->subtitle)."', " .
  777. "author = '".Database::escape_string($survey->author)."', " .
  778. "lang = '".Database::escape_string($survey->lang)."', " .
  779. "avail_from = '".Database::escape_string($survey->avail_from)."', " .
  780. "avail_till = '".Database::escape_string($survey->avail_till)."', " .
  781. "is_shared = '".Database::escape_string($survey->is_shared)."', " .
  782. "template = '".Database::escape_string($survey->template)."', " .
  783. "intro = '".Database::escape_string($survey->intro)."', " .
  784. "surveythanks = '".Database::escape_string($survey->surveythanks)."', " .
  785. "creation_date = '".Database::escape_string($survey->creation_date)."', " .
  786. "invited = '0', " .
  787. "answered = '0', " .
  788. "invite_mail = '".Database::escape_string($survey->invite_mail)."', " .
  789. "reminder_mail = '".Database::escape_string($survey->reminder_mail)."'";
  790. //Insert the new source survey
  791. api_sql_query($sql, __FILE__, __LINE__);
  792. $new_id = Database::get_last_insert_id();
  793. $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
  794. foreach ($survey->question_ids as $index => $question_id)
  795. {
  796. $qid = $this->restore_survey_question($question_id);
  797. $sql = "UPDATE ".$table_que." " .
  798. "SET survey_id = ".$new_id." WHERE " .
  799. "question_id = ".$qid."";
  800. api_sql_query($sql, __FILE__, __LINE__);
  801. $sql = "UPDATE ".$table_ans." ".
  802. "SET survey_id = ".$new_id." WHERE " .
  803. "question_id = ".$qid."";
  804. api_sql_query($sql, __FILE__, __LINE__);
  805. }
  806. break;
  807. case FILE_OVERWRITE:
  808. // Delete the existing survey with the same code and language and import the one of the source course
  809. // getting the information of the survey (used for when the survey is shared)
  810. require_once(api_get_path(SYS_CODE_PATH).'survey/survey.lib.php');
  811. $sql_select_existing_survey = "SELECT * FROM $table_sur WHERE survey_id='".Database::escape_string(Database::result($result_check,0,0))."'";
  812. $result = api_sql_query($sql_select_existing_survey, __FILE__, __LINE__);
  813. $survey_data = Database::fetch_array($result,'ASSOC');
  814. // if the survey is shared => also delete the shared content
  815. if (is_numeric($survey_data['survey_share']))
  816. {
  817. survey_manager::delete_survey($survey_data['survey_share'], true,$this->course->destination_db);
  818. }
  819. $return = survey_manager :: delete_survey($survey_data['survey_id'],false,$this->course->destination_db);
  820. //Insert the new source survey
  821. api_sql_query($sql, __FILE__, __LINE__);
  822. $new_id = Database::get_last_insert_id();
  823. $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
  824. foreach ($survey->question_ids as $index => $question_id)
  825. {
  826. $qid = $this->restore_survey_question($question_id);
  827. $sql = "UPDATE ".$table_que." " .
  828. "SET survey_id = ".$new_id." WHERE " .
  829. "question_id = ".$qid."";
  830. api_sql_query($sql, __FILE__, __LINE__);
  831. $sql = "UPDATE ".$table_ans." ".
  832. "SET survey_id = ".$new_id." WHERE " .
  833. "question_id = ".$qid."";
  834. api_sql_query($sql, __FILE__, __LINE__);
  835. }
  836. break;
  837. default:
  838. break;
  839. }
  840. }
  841. //No existing survey with the same language and the same code, we just copy the survey
  842. else
  843. {
  844. api_sql_query($sql, __FILE__, __LINE__);
  845. $new_id = Database::get_last_insert_id();
  846. $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
  847. foreach ($survey->question_ids as $index => $question_id)
  848. {
  849. $qid = $this->restore_survey_question($question_id);
  850. $sql = "UPDATE ".$table_que." " .
  851. "SET survey_id = ".$new_id." WHERE " .
  852. "question_id = ".$qid."";
  853. api_sql_query($sql, __FILE__, __LINE__);
  854. $sql = "UPDATE ".$table_ans." ".
  855. "SET survey_id = ".$new_id." WHERE " .
  856. "question_id = ".$qid."";
  857. api_sql_query($sql, __FILE__, __LINE__);
  858. }
  859. }
  860. }
  861. }
  862. }
  863. /**
  864. * Check availability of a survey code
  865. */
  866. function is_survey_code_available($survey_code)
  867. {
  868. $table_sur = Database :: get_course_table(TABLE_SURVEY, $this->course->destination_db);
  869. $sql = "SELECT * FROM $table_sur WHERE code='".Database::escape_string($survey_code)."'";
  870. $result = api_sql_query($sql, __FILE__, __LINE__);
  871. if(Database::num_rows($result) > 0) return false; else return true;
  872. }
  873. /**
  874. * Restore survey-questions
  875. */
  876. function restore_survey_question($id)
  877. {
  878. $resources = $this->course->resources;
  879. $question = $resources[RESOURCE_SURVEYQUESTION][$id];
  880. $new_id=0;
  881. if(is_object($question))
  882. {
  883. if ($question->is_restored())
  884. {
  885. return $question->destination_id;
  886. }
  887. $table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION, $this->course->destination_db);
  888. $table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION, $this->course->destination_db);
  889. $sql = "INSERT INTO ".$table_que." " .
  890. "SET survey_id = '".Database::escape_string($question->survey_id)."', " .
  891. "survey_question = '".Database::escape_string($question->survey_question)."', " .
  892. "survey_question_comment = '".Database::escape_string($question->survey_question_comment)."', " .
  893. "type = '".Database::escape_string($question->survey_question_type)."', " .
  894. "display = '".Database::escape_string($question->display)."', " .
  895. "sort = '".Database::escape_string($question->sort)."', " .
  896. "shared_question_id = '".Database::escape_string($question->shared_question_id)."', " .
  897. "max_value = '".Database::escape_string($question->max_value)."' ";
  898. api_sql_query($sql, __FILE__, __LINE__);
  899. $new_id = Database::get_last_insert_id();
  900. foreach ($question->answers as $index => $answer) {
  901. $sql = "INSERT INTO ".$table_ans." " .
  902. "SET " .
  903. "question_id = '".Database::escape_string($new_id)."', " .
  904. "option_text = '".Database::escape_string($answer['option_text'])."', " .
  905. "sort = '".Database::escape_string($answer['sort'])."', " .
  906. "survey_id = '".Database::escape_string($question->survey_id)."'";
  907. api_sql_query($sql, __FILE__, __LINE__);
  908. }
  909. $this->course->resources[RESOURCE_SURVEYQUESTION][$id]->destination_id = $new_id;
  910. }
  911. return $new_id;
  912. }
  913. /**
  914. * Restore learnpaths
  915. */
  916. function restore_learnpaths()
  917. {
  918. if ($this->course->has_resources(RESOURCE_LEARNPATH)) {
  919. $table_main = Database :: get_course_table(TABLE_LP_MAIN, $this->course->destination_db);
  920. $table_item = Database :: get_course_table(TABLE_LP_ITEM, $this->course->destination_db);
  921. $table_tool = Database::get_course_table(TABLE_TOOL_LIST, $this->course->destination_db);
  922. $resources = $this->course->resources;
  923. $prereq_old = array ();
  924. $item_old_id = array ();
  925. foreach ($resources[RESOURCE_LEARNPATH] as $id => $lp) {
  926. $sql = "INSERT INTO ".$table_main." " .
  927. "SET lp_type = '".$lp->lp_type."', " .
  928. "name = '".Database::escape_string($lp->name)."', " .
  929. "path = '".Database::escape_string($lp->path)."', " .
  930. "ref = '".$lp->ref."', " .
  931. "description = '".Database::escape_string($lp->description)."', " .
  932. "content_local = '".Database::escape_string($lp->content_local)."', " .
  933. "default_encoding = '".Database::escape_string($lp->default_encoding)."', " .
  934. "default_view_mod = '".Database::escape_string($lp->default_view_mod)."', " .
  935. "prevent_reinit = '".Database::escape_string($lp->prevent_reinit)."', " .
  936. "force_commit = '".Database::escape_string($lp->force_commit)."', " .
  937. "content_maker = '".Database::escape_string($lp->content_maker)."', " .
  938. "display_order = '".Database::escape_string($lp->display_order)."', " .
  939. "js_lib= '".Database::escape_string($lp->js_lib)."', " .
  940. "content_license= '".Database::escape_string($lp->content_license)."', " .
  941. "debug= '".Database::escape_string($lp->debug)."' ";
  942. api_sql_query($sql, __FILE__, __LINE__);
  943. $new_lp_id = Database::get_last_insert_id();
  944. if($lp->visibility) {
  945. $sql = "INSERT INTO $table_tool SET name='".Database::escape_string($lp->name)."', link='newscorm/lp_controller.php?action=view&lp_id=$new_lp_id', image='scormbuilder.gif', visibility='1', admin='0', address='squaregrey.gif'";
  946. api_sql_query($sql, __FILE__, __LINE__);
  947. }
  948. $new_item_ids = array();
  949. $parent_item_ids = array();
  950. $previous_item_ids = array();
  951. $next_item_ids = array();
  952. $old_prerequisite = array();
  953. $old_refs = array();
  954. foreach ($lp->get_items() as $index => $item) {
  955. /*
  956. if ($item['id'] != 0)
  957. {
  958. // Links in learnpath have types 'Link _self' or 'Link _blank'. We only need 'Link' here.
  959. $type_parts = explode(' ',$item['type']);
  960. $item['id'] = $this->course->resources[$type_parts[0]][$item['id']]->destination_id;
  961. }
  962. */
  963. /*
  964. //Get the new ref ID for all items that are not sco (dokeos quizzes, documents, etc)
  965. $ref = '';
  966. if(!empty($item['ref']) && $lp->lp_type!='2'){
  967. $ref = $this->get_new_id($item['item_type'],$item['ref']);
  968. } else {
  969. $ref = $item['ref'];
  970. }*/
  971. // we set the ref code here and then we update in a for loop
  972. $ref = $item['ref'];
  973. //Dealing with path the same way as ref as some data has been put into path when it's a
  974. //local resource
  975. $path = Database::escape_string($item['path']);
  976. if(strval(intval($path)) === $path) {
  977. $path = $this->get_new_id($item['item_type'],$path);
  978. }
  979. $sql = "INSERT INTO ".$table_item." SET " .
  980. "lp_id = '".Database::escape_string($new_lp_id)."', " .
  981. "item_type='".Database::escape_string($item['item_type'])."', " .
  982. "ref = '".Database::escape_string($ref)."', " .
  983. "title = '".Database::escape_string($item['title'])."', " .
  984. "description ='".Database::escape_string($item['description'])."', " .
  985. "path = '".Database::escape_string($path)."', " .
  986. "min_score = '".Database::escape_string($item['min_score'])."', " .
  987. "max_score = '".Database::escape_string($item['max_score'])."', " .
  988. "mastery_score = '".Database::escape_string($item['mastery_score'])."', " .
  989. "parent_item_id = '".Database::escape_string($item['parent_item_id'])."', " .
  990. "previous_item_id = '".Database::escape_string($item['previous_item_id'])."', " .
  991. "next_item_id = '".Database::escape_string($item['next_item_id'])."', " .
  992. "display_order = '".Database::escape_string($item['display_order'])."', " .
  993. "prerequisite = '".Database::escape_string($item['prerequisite'])."', " .
  994. "parameters='".Database::escape_string($item['parameters'])."', " .
  995. "launch_data = '".Database::escape_string($item['launch_dataprereq_type'])."'";
  996. api_sql_query($sql, __FILE__, __LINE__);
  997. $new_item_id = Database::get_last_insert_id();
  998. //save a link between old and new item IDs
  999. $new_item_ids[$item['id']] = $new_item_id;
  1000. //save a reference of items that need a parent_item_id refresh
  1001. $parent_item_ids[$new_item_id] = $item['parent_item_id'];
  1002. //save a reference of items that need a previous_item_id refresh
  1003. $previous_item_ids[$new_item_id] = $item['previous_item_id'];
  1004. //save a reference of items that need a next_item_id refresh
  1005. $next_item_ids[$new_item_id] = $item['next_item_id'];
  1006. if (!empty($item['prerequisite'])) {
  1007. if ($lp->lp_type =='2') {
  1008. // if is an sco
  1009. $old_prerequisite[$new_item_id]= $item['prerequisite'];
  1010. } else {
  1011. $old_prerequisite[$new_item_id]= $new_item_ids[$item['prerequisite']];
  1012. }
  1013. }
  1014. if (!empty($ref)) {
  1015. if ($lp->lp_type =='2') {
  1016. // if is an sco
  1017. $old_refs[$new_item_id]= $ref;
  1018. } else {
  1019. $old_refs[$new_item_id]= $new_item_ids[$ref];
  1020. }
  1021. }
  1022. }
  1023. // updating prerequisites
  1024. foreach ($old_prerequisite as $key=>$my_old_prerequisite) {
  1025. if($my_old_prerequisite != ''){
  1026. $sql = "UPDATE ".$table_item." SET prerequisite = '".$my_old_prerequisite."' WHERE id = '".$key."' ";
  1027. api_sql_query($sql, __FILE__, __LINE__);
  1028. }
  1029. }
  1030. //updating refs
  1031. foreach ($old_refs as $key=>$my_old_ref) {
  1032. if ($my_old_ref != '') {
  1033. $sql = "UPDATE ".$table_item." SET ref = '".$my_old_ref."' WHERE id = '".$key."' ";
  1034. api_sql_query($sql, __FILE__, __LINE__);
  1035. }
  1036. }
  1037. foreach ($parent_item_ids as $new_item_id => $parent_item_old_id) {
  1038. $parent_new_id = 0;
  1039. if($parent_item_old_id != 0){
  1040. $parent_new_id = $new_item_ids[$parent_item_old_id];
  1041. }
  1042. $sql = "UPDATE ".$table_item." SET parent_item_id = '".$parent_new_id."' WHERE id = '".$new_item_id."'";
  1043. api_sql_query($sql, __FILE__, __LINE__);
  1044. }
  1045. foreach ($previous_item_ids as $new_item_id => $previous_item_old_id) {
  1046. $previous_new_id = 0;
  1047. if($previous_item_old_id != 0){
  1048. $previous_new_id = $new_item_ids[$previous_item_old_id];
  1049. }
  1050. $sql = "UPDATE ".$table_item." SET previous_item_id = '".$previous_new_id."' WHERE id = '".$new_item_id."'";
  1051. api_sql_query($sql, __FILE__, __LINE__);
  1052. }
  1053. foreach ($next_item_ids as $new_item_id => $next_item_old_id) {
  1054. $next_new_id = 0;
  1055. if($next_item_old_id != 0){
  1056. $next_new_id = $new_item_ids[$next_item_old_id];
  1057. }
  1058. $sql = "UPDATE ".$table_item." SET next_item_id = '".$next_new_id."' WHERE id = '".$new_item_id."'";
  1059. api_sql_query($sql, __FILE__, __LINE__);
  1060. }
  1061. $this->course->resources[RESOURCE_LEARNPATH][$id]->destination_id = $new_lp_id;
  1062. }
  1063. }
  1064. }
  1065. /**
  1066. * restore works
  1067. */
  1068. function restore_student_publication ()
  1069. {
  1070. $my_course_id=api_get_course_id();
  1071. $my_course_info=api_get_course_info($my_course_id);//student_publication_assignment
  1072. $my_tbl_db_spa_origin=Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT,$my_course_info['dbName']);
  1073. $my_tbl_db_spa_destination = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT, $this->course->destination_db);
  1074. $my_tbl_db_origin=Database :: get_course_table(TABLE_STUDENT_PUBLICATION,$my_course_info['dbName']);
  1075. $my_tbl_db_destination = Database :: get_course_table(TABLE_STUDENT_PUBLICATION, $this->course->destination_db);
  1076. $my_tbl_db_item_property_origin=Database :: get_course_table(TABLE_ITEM_PROPERTY, $my_course_info['dbName']);
  1077. $my_tbl_db_item_property_destination=Database :: get_course_table(TABLE_ITEM_PROPERTY, $this->course->destination_db);
  1078. //query in student publication
  1079. $query_sql_fin_sp='INSERT IGNORE INTO '.$my_tbl_db_destination.'' .
  1080. '(id,url,title,description,author,active,accepted,post_group_id,sent_date,' .
  1081. 'filetype,has_properties,view_properties,qualification,date_of_qualification,' .
  1082. 'parent_id,qualificator_id,session_id) ';
  1083. $query_sql_ini_sp='SELECT id,url,title,description,author,active,accepted,post_group_id,' .
  1084. 'sent_date,filetype,has_properties,view_properties,qualification,date_of_qualification,' .
  1085. 'parent_id,qualificator_id,session_id FROM '.$my_tbl_db_origin.' WHERE filetype="folder" ';
  1086. //var_dump($query_sql_ini_sp);
  1087. $destination='../../courses/'.$this->course->destination_path.'/work/';
  1088. $course_info=api_get_course_info(api_get_course_id());
  1089. $origin='../../courses/'.$course_info['path'].'/work/';
  1090. self::allow_create_all_directory($origin,$destination,false);
  1091. //query in item property
  1092. $query_sql_fin_ip='INSERT IGNORE INTO '.$my_tbl_db_item_property_destination.'' .
  1093. '(tool,insert_user_id,insert_date,lastedit_date,ref,lastedit_type,lastedit_user_id,to_group_id,' .
  1094. 'to_user_id,visibility,start_visible,end_visible) ';
  1095. $query_sql_ini_ip='SELECT tool,insert_user_id,insert_date,lastedit_date,ref,lastedit_type,' .
  1096. 'lastedit_user_id,to_group_id,to_user_id,visibility,start_visible,
  1097. end_visible FROM '.$my_tbl_db_item_property_origin.' ip INNER JOIN '.$my_tbl_db_origin.' sp' .
  1098. ' ON ip.ref=sp.id WHERE tool="work" ';
  1099. $query_sql_fin_sa='INSERT IGNORE INTO '.$my_tbl_db_spa_destination.'' .
  1100. '(id,expires_on,ends_on,add_to_calendar,enable_qualification,publication_id) ';
  1101. $query_sql_ini_sa='SELECT sa.id,sa.expires_on,sa.ends_on,sa.add_to_calendar,sa.enable_qualification,sa.publication_id FROM '.$my_tbl_db_spa_origin.' sa INNER JOIN '.$my_tbl_db_origin.' sp
  1102. ON sa.publication_id=sp.id WHERE filetype="folder" ';
  1103. $query_sql_sp = $query_sql_fin_sp.$query_sql_ini_sp;
  1104. $query_sql_ip = $query_sql_fin_ip.$query_sql_ini_ip;
  1105. $query_sql_sa = $query_sql_fin_sa.$query_sql_ini_sa;
  1106. api_sql_query($query_sql_sp,__FILE__,__LINE__);
  1107. api_sql_query($query_sql_ip,__FILE__,__LINE__);
  1108. api_sql_query($query_sql_sa,__FILE__,__LINE__);
  1109. }
  1110. /**
  1111. * copy all directory and sub directory
  1112. * @param string The path origin
  1113. * @param string The path destination
  1114. * @param boolean Option Overwrite
  1115. * @return void()
  1116. */
  1117. function allow_create_all_directory($source, $dest, $overwrite = false){
  1118. if(!is_dir($dest)) {
  1119. mkdir($dest);
  1120. }
  1121. if ($handle = opendir($source)) { // if the folder exploration is sucsessful, continue
  1122. while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
  1123. if ($file != '.' && $file != '..') {
  1124. $path = $source . '/' . $file;
  1125. if (is_file($path)) {
  1126. /* if (!is_file($dest . '/' . $file) || $overwrite)
  1127. if (!@copy($path, $dest . '/' . $file)) {
  1128. echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
  1129. }*/
  1130. } elseif(is_dir($path)) {
  1131. if (!is_dir($dest . '/' . $file))
  1132. mkdir($dest . '/' . $file);
  1133. self:: allow_create_all_directory($path, $dest . '/' . $file, $overwrite);
  1134. }
  1135. }
  1136. }
  1137. closedir($handle);
  1138. }
  1139. }
  1140. /**
  1141. * Gets the new ID of one specific tool item from the tool name and the old ID
  1142. * @param string Tool name
  1143. * @param integer Old ID
  1144. * @return integer New ID
  1145. */
  1146. function get_new_id($tool,$ref)
  1147. {
  1148. //transform $tool into one backup/restore constant
  1149. if($tool == 'hotpotatoes'){$tool = 'document';}
  1150. if(!empty($this->course->resources[$tool][$ref]->destination_id)){
  1151. return $this->course->resources[$tool][$ref]->destination_id;
  1152. }
  1153. return '';
  1154. }
  1155. /**
  1156. * Restore glossary
  1157. */
  1158. function restore_glossary()
  1159. {
  1160. if ($this->course->has_resources(RESOURCE_GLOSSARY))
  1161. {
  1162. $table_glossary = Database :: get_course_table(TABLE_GLOSSARY, $this->course->destination_db);
  1163. $t_item_propery = Database :: get_course_table(TABLE_ITEM_PROPERTY, $this->course->destination_db);
  1164. $resources = $this->course->resources;
  1165. foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
  1166. $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $glossary->glossary_id;
  1167. $sql = "INSERT INTO ".$table_glossary." SET glossary_id = '".Database::escape_string($glossary->glossary_id)."', name = '".Database::escape_string($glossary->name)."', description = '".Database::escape_string($glossary->description)."', display_order='".Database::escape_string($glossary->display_order)."'";
  1168. Database::query($sql, __FILE__, __LINE__);
  1169. }
  1170. }
  1171. }
  1172. }
  1173. ?>