Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chamilo-lms/main/coursecopy/classes/CourseArchiver.class.php

228 lines
9.5 KiB

<?php
/* For licensing terms, see /license.txt */
require_once 'Course.class.php';
/**
* Some functions to write a course-object to a zip-file and to read a course-
* object from such a zip-file.
* @author Bart Mollet <bart.mollet@hogent.be>
* @package chamilo.backup
*
* @todo Use archive-folder of Chamilo?
*/
class CourseArchiver
{
/**
* Delete old temp-dirs
*/
static function clean_backup_dir() {
$dir = api_get_path(SYS_ARCHIVE_PATH);
if ($handle = @ opendir($dir)) {
while (($file = readdir($handle)) !== false) {
if ($file != "." && $file != ".." && strpos($file, 'CourseArchiver_') === 0 && is_dir($dir . '/' . $file)) {
api_rmdirr($dir . '/' . $file);
}
}
closedir($handle);
}
}
/**
* Write a course and all its resources to a zip-file.
* @return string A pointer to the zip-file
*/
static function write_course($course)
{
$perm_dirs = api_get_permissions_for_new_directories();
CourseArchiver::clean_backup_dir();
// Create a temp directory
$tmp_dir_name = 'CourseArchiver_'.api_get_unique_id();
$backup_dir = api_get_path(SYS_ARCHIVE_PATH).$tmp_dir_name . '/';
// All course-information will be stored in course_info.dat
$course_info_file = $backup_dir.'course_info.dat';
$zip_dir = api_get_path(SYS_ARCHIVE_PATH);
$user = api_get_user_info();
$date = new DateTime(api_get_local_time());
$zip_file = $user['user_id'] . '_' . $course->code . '_' . $date->format('Ymd-His') . '.zip';
$php_errormsg = '';
$res = @mkdir($backup_dir, $perm_dirs);
if ($res === false) {
//TODO set and handle an error message telling the user to review the permissions on the archive directory
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);
}
// Write the course-object to the file
$fp = @fopen($course_info_file, 'w');
if ($fp === false) {
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);
}
$res = @fwrite($fp, base64_encode(serialize($course)));
if ($res === false) {
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);
}
$res = @fclose($fp);
if ($res === false) {
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);
}
// Copy all documents to the temp-dir
if (isset($course->resources[RESOURCE_DOCUMENT]) && is_array($course->resources[RESOURCE_DOCUMENT])) {
foreach ($course->resources[RESOURCE_DOCUMENT] as $document) {
if ($document->file_type == DOCUMENT) {
$doc_dir = $backup_dir . $document->path;
@mkdir(dirname($doc_dir), $perm_dirs, true);
if (file_exists($course->path . $document->path)) {
copy($course->path . $document->path, $doc_dir);
}
} else {
@mkdir($backup_dir . $document->path, $perm_dirs, true);
}
}
}
// Copy all scorm documents to the temp-dir
if (isset($course->resources[RESOURCE_SCORM]) && is_array($course->resources[RESOURCE_SCORM])) {
foreach ($course->resources[RESOURCE_SCORM] as $document) {
$doc_dir = dirname($backup_dir . $document->path);
@mkdir($doc_dir, $perm_dirs, true);
FileManager::copyDirTo($course->path . $document->path, $doc_dir, false);
}
}
// Copy calendar attachments.
if (isset($course->resources[RESOURCE_EVENT]) && is_array($course->resources[RESOURCE_EVENT])) {
$doc_dir = dirname($backup_dir . '/upload/calendar/');
@mkdir($doc_dir, $perm_dirs, true);
FileManager::copyDirTo($course->path . 'upload/calendar/', $doc_dir, false);
}
// Copy Learning path author image.
if (isset($course->resources[RESOURCE_LEARNPATH]) && is_array($course->resources[RESOURCE_LEARNPATH])) {
$doc_dir = dirname($backup_dir . '/upload/learning_path/');
@mkdir($doc_dir, $perm_dirs, true);
FileManager::copyDirTo($course->path . 'upload/learning_path/', $doc_dir, false);
}
// Copy announcements attachments.
if (isset($course->resources[RESOURCE_ANNOUNCEMENT]) && is_array($course->resources[RESOURCE_ANNOUNCEMENT])) {
$doc_dir = dirname($backup_dir . '/upload/announcements/');
@mkdir($doc_dir, $perm_dirs, true);
FileManager::copyDirTo($course->path . 'upload/announcements/', $doc_dir, false);
}
// Copy work folders (only folders)
if (isset($course->resources[RESOURCE_WORK]) && is_array($course->resources[RESOURCE_WORK])) {
$doc_dir = dirname($backup_dir . '/upload/work/');
@mkdir($doc_dir, $perm_dirs, true);
// @todo: adjust to only create subdirs, but not copy files
Merge branch 'chamilo19' Conflicts: 404.php documentation/changelog.html documentation/dependencies.html documentation/installation_guide.html documentation/optimization.html main/admin/careers.php main/admin/course_category.php main/admin/course_edit.php main/admin/course_import.php main/admin/index.php main/admin/session_import.php main/admin/session_list.php main/admin/user_add.php main/admin/user_list.php main/auth/courses.php main/auth/courses_controller.php main/auth/inscription.php main/auth/profile.php main/calendar/agenda.inc.php main/calendar/agenda.lib.php main/coursecopy/classes/Announcement.class.php main/coursecopy/classes/Attendance.class.php main/coursecopy/classes/Course.class.php main/coursecopy/classes/CourseArchiver.class.php main/coursecopy/classes/CourseBuilder.class.php main/coursecopy/classes/CourseRecycler.class.php main/coursecopy/classes/CourseRestorer.class.php main/coursecopy/classes/CourseSelectForm.class.php main/css/base.css main/css/bootstrap.css main/css/chamilo/images/header-logo.png main/css/responsive.css main/document/create_audio.php main/document/document.php main/document/download.php main/exercice/answer.class.php main/exercice/exercise.class.php main/exercice/exercise.lib.php main/exercice/exercise_result.class.php main/exercice/exercise_result.php main/exercice/exercise_show.php main/exercice/exercise_submit.php main/exercice/fill_blanks.class.php main/exercice/question.class.php main/exercice/question_list_admin.inc.php main/exercice/question_pool.php main/exercice/testcategory.class.php main/gradebook/index.php main/gradebook/lib/be/category.class.php main/gradebook/lib/fe/flatviewtable.class.php main/gradebook/lib/scoredisplay.class.php main/inc/ajax/agenda.ajax.php main/inc/ajax/exercise.ajax.php main/inc/ajax/model.ajax.php main/inc/global.inc.php main/inc/lib/add_course.lib.inc.php main/inc/lib/add_courses_to_session_functions.lib.php main/inc/lib/autoload.class.php main/inc/lib/banner.lib.php main/inc/lib/career.lib.php main/inc/lib/course.lib.php main/inc/lib/course_home.lib.php main/inc/lib/display.lib.php main/inc/lib/document.lib.php main/inc/lib/exercise_show_functions.lib.php main/inc/lib/groupmanager.lib.php main/inc/lib/javascript/jqgrid/js/jquery.jqGrid.min.js main/inc/lib/javascript/jquery.lp_minipanel.js main/inc/lib/link.lib.php main/inc/lib/log.class.php main/inc/lib/login.lib.php main/inc/lib/main_api.lib.php main/inc/lib/message.lib.php main/inc/lib/pear/HTML/QuickForm.php main/inc/lib/promotion.lib.php main/inc/lib/security.lib.php main/inc/lib/sessionmanager.lib.php main/inc/lib/symfony/Monolog/Handler/NativeMailerHandler.php main/inc/lib/usermanager.lib.php main/inc/lib/userportal.lib.php main/inc/local.inc.php main/install/index.php main/install/update-db-1.8.7-1.8.8.inc.php main/install/version.php main/lang/basque/course_info.inc.php main/lang/english/trad4all.inc.php main/lang/greek/admin.inc.php main/lang/greek/course_home.inc.php main/lang/greek/courses.inc.php main/lang/greek/messages.inc.php main/lang/greek/registration.inc.php main/lang/greek/reservation.inc.php main/lang/greek/survey.inc.php main/lang/greek/trad4all.inc.php main/lang/spanish/admin.inc.php main/lang/spanish/trad4all.inc.php main/mySpace/index.php main/newscorm/learnpath.class.php main/newscorm/scorm_api.php main/social/search.php main/survey/survey.lib.php main/template/default/admin/settings_index.tpl main/template/default/agenda/month.tpl main/template/default/layout/footer.tpl main/template/default/layout/head.tpl main/template/default/layout/login_form.tpl main/upload/upload_word.php main/user/user_import.php main/wiki/wiki.inc.php main/work/view.php main/work/work.lib.php main/work/work.php tests/phpunit/classes/UserManagerTest.lib.php
13 years ago
FileManager::copyDirTo($course->path . 'upload/work/', $doc_dir, false);
}
// Zip the course-contents
$zip = new PclZip($zip_dir . $zip_file);
$zip->create($zip_dir . $tmp_dir_name, PCLZIP_OPT_REMOVE_PATH, $zip_dir . $tmp_dir_name . '/');
//$zip->deleteByIndex(0);
// Remove the temp-dir.
api_rmdirr($backup_dir);
return $zip_file;
}
/**
*
*/
static function get_available_backups($user_id = null) {
$backup_files = array();
$dirname = api_get_path(SYS_ARCHIVE_PATH) . '';
if ($dir = opendir($dirname)) {
while (($file = readdir($dir)) !== false) {
$file_parts = explode('_', $file);
if (count($file_parts) == 3) {
$owner_id = $file_parts[0];
$course_code = $file_parts[1];
$file_parts = explode('.', $file_parts[2]);
$date = $file_parts[0];
$ext = $file_parts[1];
if ($ext == 'zip' && ($user_id != null && $owner_id == $user_id || $user_id == null)) {
$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);
$backup_files[] = array('file' => $file, 'date' => $date, 'course_code' => $course_code);
}
}
}
closedir($dir);
}
return $backup_files;
}
/**
*
*/
static function import_uploaded_file($file) {
$new_filename = uniqid('') . '.zip';
$new_dir = api_get_path(SYS_ARCHIVE_PATH);
if (is_dir($new_dir) && is_writable($new_dir)) {
move_uploaded_file($file, api_get_path(SYS_ARCHIVE_PATH).$new_filename);
return $new_filename;
}
return false;
}
/**
* Read a course-object from a zip-file
* @return course The course
* @param boolean $delete Delete the file after reading the course?
* @todo Check if the archive is a correct Chamilo-export
*/
static function read_course($filename, $delete = false)
{
CourseArchiver::clean_backup_dir();
// Create a temp directory
$tmp_dir_name = 'CourseArchiver_' . uniqid('');
$unzip_dir = api_get_path(SYS_ARCHIVE_PATH).$tmp_dir_name;
mkdir($unzip_dir, api_get_permissions_for_new_directories(), true);
copy(api_get_path(SYS_ARCHIVE_PATH).$filename, $unzip_dir.'/backup.zip');
// unzip the archive
$zip = new PclZip($unzip_dir.'/backup.zip');
chdir($unzip_dir);
$list = $zip->extract(PCLZIP_OPT_TEMP_FILE_ON);
if ($list == 0) {
/*global $app;
$errorMessage = $zip->errorInfo(true);
$app['session']->getFlashBag()->add('warning', $errorMessage);*/
}
// remove the archive-file
if ($delete) {
if (file_exists(api_get_path(SYS_ARCHIVE_PATH).$filename)) {
unlink(api_get_path(SYS_ARCHIVE_PATH).$filename);
}
}
// Read the course
if (!is_file('course_info.dat')) {
return new Course();
}
$contents = file_get_contents('course_info.dat');
// CourseCopyLearnpath class appeared in Chamilo 1.8.7, it is the former Learnpath class in the "Copy course" tool.
// For backward comaptibility with archives created on Chamilo 1.8.6.2 or older systems, we have to do the following:
// Before unserialization, if class name "Learnpath" was found, it should be renamed as "CourseCopyLearnpath".
$course = unserialize(str_replace('O:9:"Learnpath":', 'O:19:"CourseCopyLearnpath":', base64_decode($contents)));
if (get_class($course) != 'Course') {
return new Course();
}
$course->backup_path = $unzip_dir;
return $course;
}
}