PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/main/coursecopy/classes/CourseArchiver.class.php

https://bitbucket.org/hanutimes/hanutimes
PHP | 209 lines | 139 code | 22 blank | 48 comment | 43 complexity | 7e45692c19baa83c247736d713bf5de7 MD5 | raw file
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. require_once 'Course.class.php';
  4. /**
  5. * Some functions to write a course-object to a zip-file and to read a course-
  6. * object from such a zip-file.
  7. * @author Bart Mollet <bart.mollet@hogent.be>
  8. * @package chamilo.backup
  9. *
  10. * @todo Use archive-folder of Chamilo?
  11. */
  12. class CourseArchiver
  13. {
  14. /**
  15. * Delete old temp-dirs
  16. */
  17. static function clean_backup_dir() {
  18. $dir = api_get_path(SYS_ARCHIVE_PATH);
  19. if ($handle = @ opendir($dir)) {
  20. while (($file = readdir($handle)) !== false) {
  21. if ($file != "." && $file != ".." && strpos($file, 'CourseArchiver_') === 0 && is_dir($dir . '/' . $file)) {
  22. rmdirr($dir . '/' . $file);
  23. }
  24. }
  25. closedir($handle);
  26. }
  27. }
  28. /**
  29. * Write a course and all its resources to a zip-file.
  30. * @return string A pointer to the zip-file
  31. */
  32. static function write_course($course) {
  33. $perm_dirs = api_get_permissions_for_new_directories();
  34. CourseArchiver::clean_backup_dir();
  35. // Create a temp directory
  36. $tmp_dir_name = 'CourseArchiver_' . api_get_unique_id();
  37. $backup_dir = api_get_path(SYS_ARCHIVE_PATH) . $tmp_dir_name . '/';
  38. // All course-information will be stored in course_info.dat
  39. $course_info_file = $backup_dir . 'course_info.dat';
  40. $zip_dir = api_get_path(SYS_ARCHIVE_PATH);
  41. $user = api_get_user_info();
  42. $date = new DateTime(api_get_local_time());
  43. $zip_file = $user['user_id'] . '_' . $course->code . '_' . $date->format('Ymd-His') . '.zip';
  44. $php_errormsg = '';
  45. $res = @mkdir($backup_dir, $perm_dirs);
  46. if ($res === false) {
  47. //TODO set and handle an error message telling the user to review the permissions on the archive directory
  48. error_log(__FILE__ . ' line ' . __LINE__ . ': ' . (ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini') . ' - This error, occuring because your archive directory will not let this script write data into it, will prevent courses backups to be created', 0);
  49. }
  50. // Write the course-object to the file
  51. $fp = @fopen($course_info_file, 'w');
  52. if ($fp === false) {
  53. error_log(__FILE__ . ' line ' . __LINE__ . ': ' . (ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
  54. }
  55. $res = @fwrite($fp, base64_encode(serialize($course)));
  56. if ($res === false) {
  57. error_log(__FILE__ . ' line ' . __LINE__ . ': ' . (ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
  58. }
  59. $res = @fclose($fp);
  60. if ($res === false) {
  61. error_log(__FILE__ . ' line ' . __LINE__ . ': ' . (ini_get('track_errors') != false ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0);
  62. }
  63. //Documents
  64. // Copy all documents to the temp-dir
  65. if (is_array($course->resources[RESOURCE_DOCUMENT])) {
  66. foreach ($course->resources[RESOURCE_DOCUMENT] as $id => $document) {
  67. if ($document->file_type == DOCUMENT) {
  68. $doc_dir = $backup_dir . $document->path;
  69. @mkdir(dirname($doc_dir), $perm_dirs, true);
  70. if (file_exists($course->path . $document->path)) {
  71. copy($course->path . $document->path, $doc_dir);
  72. }
  73. } else {
  74. @mkdir($backup_dir . $document->path, $perm_dirs, true);
  75. }
  76. }
  77. }
  78. // Copy all scorm documents to the temp-dir
  79. if (is_array($course->resources[RESOURCE_SCORM])) {
  80. foreach ($course->resources[RESOURCE_SCORM] as $id => $document) {
  81. $doc_dir = dirname($backup_dir . $document->path);
  82. @mkdir($doc_dir, $perm_dirs, true);
  83. FileManager::copyDirTo($course->path . $document->path, $doc_dir, false);
  84. }
  85. }
  86. //Copy calendar attachments
  87. if (is_array($course->resources[RESOURCE_EVENT])) {
  88. $doc_dir = dirname($backup_dir . '/upload/calendar/');
  89. @mkdir($doc_dir, $perm_dirs, true);
  90. FileManager::copyDirTo($course->path . 'upload/calendar/', $doc_dir, false);
  91. }
  92. //Copy learningpath author image
  93. if (is_array($course->resources[RESOURCE_LEARNPATH])) {
  94. $doc_dir = dirname($backup_dir . '/upload/learning_path/');
  95. @mkdir($doc_dir, $perm_dirs, true);
  96. FileManager::copyDirTo($course->path . 'upload/learning_path/', $doc_dir, false);
  97. }
  98. //Copy announcements attachments
  99. if (is_array($course->resources[RESOURCE_ANNOUNCEMENT])) {
  100. $doc_dir = dirname($backup_dir . '/upload/announcements/');
  101. @mkdir($doc_dir, $perm_dirs, true);
  102. FileManager::copyDirTo($course->path . 'upload/announcements/', $doc_dir, false);
  103. }
  104. // Zip the course-contents
  105. $zip = new PclZip($zip_dir . $zip_file);
  106. $zip->create($zip_dir . $tmp_dir_name, PCLZIP_OPT_REMOVE_PATH, $zip_dir . $tmp_dir_name . '/');
  107. //$zip->deleteByIndex(0);
  108. // Remove the temp-dir.
  109. rmdirr($backup_dir);
  110. return '' . $zip_file;
  111. }
  112. /**
  113. *
  114. */
  115. static function get_available_backups($user_id = null) {
  116. $backup_files = array();
  117. $dirname = api_get_path(SYS_ARCHIVE_PATH) . '';
  118. if ($dir = opendir($dirname)) {
  119. while (($file = readdir($dir)) !== false) {
  120. $file_parts = explode('_', $file);
  121. if (count($file_parts) == 3) {
  122. $owner_id = $file_parts[0];
  123. $course_code = $file_parts[1];
  124. $file_parts = explode('.', $file_parts[2]);
  125. $date = $file_parts[0];
  126. $ext = $file_parts[1];
  127. if ($ext == 'zip' && ($user_id != null && $owner_id == $user_id || $user_id == null)) {
  128. $date = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2) . ' ' . substr($date, 8, 2) . ':' . substr($date, 10, 2) . ':' . substr($date, 12, 2);
  129. $backup_files[] = array('file' => $file, 'date' => $date, 'course_code' => $course_code);
  130. }
  131. }
  132. }
  133. closedir($dir);
  134. }
  135. return $backup_files;
  136. }
  137. /**
  138. *
  139. */
  140. static function import_uploaded_file($file) {
  141. $new_filename = uniqid('') . '.zip';
  142. $new_dir = api_get_path(SYS_ARCHIVE_PATH);
  143. if (is_dir($new_dir) && is_writable($new_dir)) {
  144. move_uploaded_file($file, api_get_path(SYS_ARCHIVE_PATH).$new_filename);
  145. return $new_filename;
  146. }
  147. return false;
  148. }
  149. /**
  150. * Read a course-object from a zip-file
  151. * @return course The course
  152. * @param boolean $delete Delete the file after reading the course?
  153. * @todo Check if the archive is a correct Chamilo-export
  154. */
  155. static function read_course($filename, $delete = false) {
  156. CourseArchiver::clean_backup_dir();
  157. // Create a temp directory
  158. $tmp_dir_name = 'CourseArchiver_' . uniqid('');
  159. $unzip_dir = api_get_path(SYS_ARCHIVE_PATH) . '' . $tmp_dir_name;
  160. @mkdir($unzip_dir, api_get_permissions_for_new_directories(), true);
  161. @copy(api_get_path(SYS_ARCHIVE_PATH) . '' . $filename, $unzip_dir . '/backup.zip');
  162. // unzip the archive
  163. $zip = new PclZip($unzip_dir . '/backup.zip');
  164. @chdir($unzip_dir);
  165. $zip->extract(PCLZIP_OPT_TEMP_FILE_ON);
  166. // remove the archive-file
  167. if ($delete) {
  168. @unlink(api_get_path(SYS_ARCHIVE_PATH) . '' . $filename);
  169. }
  170. // read the course
  171. if (!is_file('course_info.dat')) {
  172. return new Course();
  173. }
  174. $fp = @fopen('course_info.dat', "r");
  175. $contents = @fread($fp, filesize('course_info.dat'));
  176. @fclose($fp);
  177. // CourseCopyLearnpath class appeared in Chamilo 1.8.7, it is the former Learnpath class in the "Copy course" tool.
  178. // For backward comaptibility with archives created on Chamilo 1.8.6.2 or older systems, we have to do the following:
  179. // Before unserialization, if class name "Learnpath" was found, it should be renamed as "CourseCopyLearnpath".
  180. $course = unserialize(str_replace('O:9:"Learnpath":', 'O:19:"CourseCopyLearnpath":', base64_decode($contents)));
  181. if (get_class($course) != 'Course') {
  182. return new Course();
  183. }
  184. $course->backup_path = $unzip_dir;
  185. return $course;
  186. }
  187. }