/** * Create the dummy course */ function create_dummy_course($course_code) { $this->default_property['insert_user_id'] = '1'; $this->default_property['insert_date'] = date('Y-m-d H:i:s'); $this->default_property['lastedit_date'] = date('Y-m-d H:i:s'); $this->default_property['lastedit_user_id'] = '1'; $this->default_property['to_group_id'] = '0'; $this->default_property['to_user_id'] = null; $this->default_property['visibility'] = '1'; $this->default_property['start_visible'] = '0000-00-00 00:00:00'; $this->default_property['end_visible'] = '0000-00-00 00:00:00'; $course = api_get_course_info($course_code); $this->course = new Course(); $tmp_path = api_get_path(SYS_COURSE_PATH) . $course['directory'] . '/document/tmp_' . uniqid(''); @mkdir($tmp_path, api_get_permissions_for_new_directories(), true); $this->course->backup_path = $tmp_path; $this->create_dummy_links(); $this->create_dummy_events(); $this->create_dummy_forums(); $this->create_dummy_announcements(); $this->create_dummy_documents(); $this->create_dummy_learnpaths(); $cr = new CourseRestorer($this->course); $cr->set_file_option(FILE_OVERWRITE); $cr->restore($course_code); api_rmdirr($tmp_path); }
/** * Restore scorm documents * TODO @TODO check that the restore function with renaming doesn't break the scorm structure! */ function restore_scorm_documents() { $perm = api_get_permissions_for_new_directories(); if ($this->course->has_resources(RESOURCE_SCORM)) { $resources = $this->course->resources; foreach ($resources[RESOURCE_SCORM] as $id => $document) { $path = api_get_path(SYS_COURSE_PATH) . $this->course->destination_path . '/'; @mkdir(dirname($path . $document->path), $perm, true); if (file_exists($path . $document->path)) { switch ($this->file_option) { case FILE_OVERWRITE: api_rmdirr($path . $document->path); FileManager::copyDirTo($this->course->backup_path . '/' . $document->path, $path . dirname($document->path), false); break; case FILE_SKIP: break; case FILE_RENAME: $i = 1; $ext = explode('.', basename($document->path)); if (count($ext) > 1) { $ext = array_pop($ext); $file_name_no_ext = substr($document->path, 0, -(strlen($ext) + 1)); $ext = '.' . $ext; } else { $ext = ''; $file_name_no_ext = $document->path; } $new_file_name = $file_name_no_ext . '_' . $i . $ext; $file_exists = file_exists($path . $new_file_name); while ($file_exists) { $i++; $new_file_name = $file_name_no_ext . '_' . $i . $ext; $file_exists = file_exists($path . $new_file_name); } rename($this->course->backup_path . '/' . $document->path, $this->course->backup_path . '/' . $new_file_name); FileManager::copyDirTo($this->course->backup_path . '/' . $new_file_name, $path . dirname($new_file_name), false); rename($this->course->backup_path . '/' . $new_file_name, $this->course->backup_path . '/' . $document->path); break; } // end switch } else { FileManager::copyDirTo($this->course->backup_path . '/' . $document->path, $path . dirname($document->path), false); } } // end for each } }
/** * Static admin function allowing removal of a learnpath * @param string Course code * @param integer Learnpath ID * @param string Whether to delete data or keep it (default: 'keep', others: 'remove') * @return boolean True on success, false on failure (might change that to return number of elements deleted) */ public function delete($course = null, $id = null, $delete = 'keep') { $course_id = api_get_course_int_id(); // TODO: Implement a way of getting this to work when the current object is not set. // In clear: implement this in the item class as well (abstract class) and use the given ID in queries. //if (empty($course)) { $course = api_get_course_id(); } //if (empty($id)) { $id = $this->get_id(); } // If an ID is specifically given and the current LP is not the same, prevent delete. if (!empty($id) && $id != $this->lp_id) { return false; } $lp = Database::get_course_table(TABLE_LP_MAIN); $lp_item = Database::get_course_table(TABLE_LP_ITEM); // Proposed by Christophe (clefevre), see below. $lp_view = Database::get_course_table(TABLE_LP_VIEW); $lp_item_view = Database::get_course_table(TABLE_LP_ITEM_VIEW); //if ($this->debug > 0) { error_log('New LP - In learnpath::delete()', 0); } // Delete lp item id. foreach ($this->items as $id => $dummy) { //$this->items[$id]->delete(); $sql_del_view = "DELETE FROM {$lp_item_view} WHERE c_id = {$course_id} AND lp_item_id = '" . $id . "'"; $res_del_item_view = Database::query($sql_del_view); } // Proposed by Christophe (nickname: clefevre), see http://www.dokeos.com/forum/viewtopic.php?t=29673 $sql_del_item = "DELETE FROM {$lp_item} WHERE c_id = " . $course_id . " AND lp_id = " . $this->lp_id; $res_del_item = Database::query($sql_del_item); $sql_del_view = "DELETE FROM {$lp_view} WHERE c_id = " . $course_id . " AND lp_id = " . $this->lp_id; //if ($this->debug > 2) { error_log('New LP - Deleting views bound to lp '.$this->lp_id.': '.$sql_del_view, 0); } $res_del_view = Database::query($sql_del_view); self::toggle_publish($this->lp_id, 'i'); //if ($this->debug > 2) { error_log('New LP - Deleting lp '.$this->lp_id.' of type '.$this->type, 0); } if ($this->type == 2 || $this->type == 3) { // This is a scorm learning path, delete the files as well. $sql = "SELECT path FROM {$lp} WHERE c_id = " . $course_id . " AND id = " . $this->lp_id; $res = Database::query($sql); if (Database::num_rows($res) > 0) { $row = Database::fetch_array($res); $path = $row['path']; $sql = "SELECT id FROM {$lp} WHERE c_id = " . $course_id . " AND path = '{$path}' AND id != " . $this->lp_id; $res = Database::query($sql); if (Database::num_rows($res) > 0) { // Another learning path uses this directory, so don't delete it. if ($this->debug > 2) { error_log('New LP - In learnpath::delete(), found other LP using path ' . $path . ', keeping directory', 0); } } else { // No other LP uses that directory, delete it. $course_rel_dir = api_get_course_path() . '/scorm/'; // scorm dir web path starting from /courses $course_scorm_dir = api_get_path(SYS_COURSE_PATH) . $course_rel_dir; // The absolute system path for this course. if ($delete == 'remove' && is_dir($course_scorm_dir . $path) and !empty($course_scorm_dir)) { if ($this->debug > 2) { error_log('New LP - In learnpath::delete(), found SCORM, deleting directory: ' . $course_scorm_dir . $path, 0); } // Proposed by Christophe (clefevre). if (strcmp(substr($path, -2), "/.") == 0) { $path = substr($path, 0, -1); // Remove "." at the end. } //exec('rm -rf ' . $course_scorm_dir . $path); // See Bug #5208, this is not OS-portable way. api_rmdirr($course_scorm_dir . $path); } } } } $sql_del_lp = "DELETE FROM {$lp} WHERE c_id = " . $course_id . " AND id = " . $this->lp_id; //if ($this->debug > 2) { error_log('New LP - Deleting lp '.$this->lp_id.': '.$sql_del_lp, 0); } $res_del_lp = Database::query($sql_del_lp); $this->update_display_order(); // Updates the display order of all lps. api_item_property_update(api_get_course_info(), TOOL_LEARNPATH, $this->lp_id, 'delete', api_get_user_id()); require_once api_get_path(SYS_CODE_PATH) . 'gradebook/lib/be.inc.php'; // Delete link of gradebook tool //$tbl_grade_link = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK); /*$sql = 'SELECT gl.id FROM ' . $tbl_grade_link . ' gl WHERE gl.type="4" AND gl.ref_id="' . $id . '";'; $result = Database::query($sql); $row = Database :: fetch_array($result, 'ASSOC');*/ // Fixing gradebook link deleted see #5229. /* if (!empty($row['id'])) { $link = LinkFactory :: load($row['id']); if ($link[0] != null) { $link[0]->delete(); } }*/ require_once api_get_path(SYS_CODE_PATH) . 'gradebook/lib/gradebook_functions.inc.php'; $link_info = is_resource_in_course_gradebook(api_get_course_id(), 4, $id, api_get_session_id()); if ($link_info !== false) { remove_resource_from_course_gradebook($link_info['id']); } if (api_get_setting('search_enabled') == 'true') { require_once api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php'; $r = delete_all_values_for_item($this->cc, TOOL_LEARNPATH, $this->lp_id); } }
/** * 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 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; }
$cidReset = true; // including some necessary files require_once '../inc/global.inc.php'; // setting the section (for the tabs) $this_section = SECTION_PLATFORM_ADMIN; // Access restrictions api_protect_admin_script(true); // setting breadcrumbs $interbreadcrumb[] = array('url' => 'index.php', 'name' => get_lang('PlatformAdmin')); $form = new FormValidator('archive_cleanup_form'); $form->addElement('style_submit_button', 'proceed', get_lang('ArchiveDirCleanupProceedButton'), 'class="save"'); $message = null; if ($form->validate()) { $archive_path = api_get_path(SYS_ARCHIVE_PATH); $htaccess = @file_get_contents($archive_path . '.htaccess'); $result = api_rmdirr($archive_path, true); if (!empty($htaccess)) { @file_put_contents($archive_path . '/.htaccess', $htaccess); } if ($result) { // Creating temp folders /** @var ChamiloLMS\Component\DataFilesystem\DataFilesystem $filesystem */ $filesystem = $app['chamilo.filesystem']; $filesystem->createFolders($app['temp.paths']->folders); $message = 'ArchiveDirCleanupSucceeded'; $type = 'confirmation'; } else { $message = 'ArchiveDirCleanupFailed'; $type = 'error'; } header('Location: ' . api_get_self() . '?msg=' . $message . '&type=' . $type);
/** * Recycle learning paths */ public function recycle_learnpaths() { if ($this->course->has_resources(RESOURCE_LEARNPATH)) { $table_main = Database::get_course_table(TABLE_LP_MAIN); $table_item = Database::get_course_table(TABLE_LP_ITEM); $table_view = Database::get_course_table(TABLE_LP_VIEW); $table_iv = Database::get_course_table(TABLE_LP_ITEM_VIEW); $table_iv_int = Database::get_course_table(TABLE_LP_IV_INTERACTION); $table_tool = Database::get_course_table(TABLE_TOOL_LIST); foreach ($this->course->resources[RESOURCE_LEARNPATH] as $id => $learnpath) { // See task #875. if ($learnpath->lp_type == 2) { // This is a learning path of SCORM type. // A sanity check for avoiding removal of the parent folder scorm/ if (trim($learnpath->path) != '') { // when $learnpath->path value is incorrect for some reason. // The directory trat contains files of the SCORM package is to be deleted. $scorm_package_dir = realpath($this->course->path . 'scorm/' . $learnpath->path); api_rmdirr($scorm_package_dir); } } //remove links from course homepage $sql = "DELETE FROM {$table_tool}\n WHERE c_id = " . $this->course_id . " AND link LIKE '%lp_controller.php%lp_id={$id}%' AND image='scormbuilder.gif'"; Database::query($sql); //remove elements from lp_* tables (from bottom-up) by removing interactions, then item_view, then views and items, then paths $sql_items = "SELECT id FROM {$table_item}\n WHERE c_id = " . $this->course_id . " AND lp_id={$id}"; $res_items = Database::query($sql_items); while ($row_item = Database::fetch_array($res_items)) { //get item views $sql_iv = "SELECT id FROM {$table_iv}\n WHERE c_id = " . $this->course_id . " AND lp_item_id=" . $row_item['id']; $res_iv = Database::query($sql_iv); while ($row_iv = Database::fetch_array($res_iv)) { //delete interactions $sql_iv_int_del = "DELETE FROM {$table_iv_int}\n WHERE c_id = " . $this->course_id . " AND lp_iv_id = " . $row_iv['id']; Database::query($sql_iv_int_del); } //delete item views $sql_iv_del = "DELETE FROM {$table_iv}\n WHERE c_id = " . $this->course_id . " AND lp_item_id=" . $row_item['id']; Database::query($sql_iv_del); } //delete items $sql_items_del = "DELETE FROM {$table_item} WHERE c_id = " . $this->course_id . " AND lp_id={$id}"; Database::query($sql_items_del); //delete views $sql_views_del = "DELETE FROM {$table_view} WHERE c_id = " . $this->course_id . " AND lp_id={$id}"; Database::query($sql_views_del); //delete lps $sql_del = "DELETE FROM {$table_main} WHERE c_id = " . $this->course_id . " AND id = {$id}"; Database::query($sql_del); } } }
/** * Deletes a file, or a folder and its contents * * @author Aidan Lister <*****@*****.**> * @version 1.0.3 * @param string $dirname Directory to delete * @param bool Deletes only the content or not * @return bool Returns TRUE on success, FALSE on failure * @link http://aidanlister.com/2004/04/recursively-deleting-a-folder-in-php/ * @author Yannick Warnier, adaptation for the Chamilo LMS, April, 2008 * @author Ivan Tcholakov, a sanity check about Directory class creation has been added, September, 2009 */ function api_rmdirr($dirname, $delete_only_content_in_folder = false) { $res = true; // A sanity check. if (!file_exists($dirname)) { return false; } $php_errormsg = ''; // Simple delete for a file. if (is_file($dirname) || is_link($dirname)) { $res = unlink($dirname); if ($res === false) { error_log(__FILE__ . ' line ' . __LINE__ . ': ' . ((bool) ini_get('track_errors') ? $php_errormsg : 'Error not recorded because track_errors is off in your php.ini'), 0); } return $res; } // Loop through the folder. $dir = dir($dirname); // A sanity check. $is_object_dir = is_object($dir); if ($is_object_dir) { while (false !== ($entry = $dir->read())) { // Skip pointers. if ($entry == '.' || $entry == '..') { continue; } // Recurse. api_rmdirr("{$dirname}/{$entry}"); } } // Clean up. if ($is_object_dir) { $dir->close(); } if ($delete_only_content_in_folder == false) { $res = rmdir($dirname); if ($res === false) { error_log(__FILE__ . ' line ' . __LINE__ . ': ' . ((bool) ini_get('track_errors') ? $php_errormsg : 'error not recorded because track_errors is off in your php.ini'), 0); } } return $res; }
* Running the cleanup */ echo "Assuming " . api_get_path(SYS_PATH) . " as Chamilo directory\n"; foreach ($clean_dirs as $dir) { $list = scandir($dir); echo "Cleaning {$dir}\n"; foreach ($list as $entry) { if (substr($entry, 0, 1) == '.' or strcmp($entry, 'htaccess') === 0 or strcmp($entry, 'index.html') === 0 or substr($entry, -9, 9) == '.dist.php') { //skip files that are part of the Chamilo installation } else { if ($dir == $homepath and (is_dir($homepath . $entry) and $entry == 'default_platform_document' or !is_dir($homepath . $entry) and substr($entry, -5) == '.html' and strlen($entry) <= 17)) { //skip } else { if (is_dir($dir . $entry)) { //echo "Removing ".$dir.$entry."\n"; api_rmdirr($dir . $entry); } else { //echo "Removing ".$dir.$entry."\n"; unlink($dir . $entry); } } } } } echo "Dropping database " . $global_db . "\n"; $sql = "DROP DATABASE {$global_db}"; $res = Database::query($sql); if ($res === false) { echo "Failed dropping database. Please check manually.\n"; } else { echo "All clean!\n";
/** * This function delete the test course from the database and destroy the sessions. * @param string the course code than will be delete. * @return void */ function delete_test_course($course_code = 'TESTCOURSE') { $res = CourseManager::delete_course($course_code); $path = api_get_path(SYS_PATH) . 'archive'; if ($handle = opendir($path)) { while (false !== ($file = readdir($handle))) { if (strpos($file, $course_code) !== false) { if (is_dir($path . '/' . $file)) { api_rmdirr($path . '/' . $file); } } } closedir($handle); } // Check api session destroy if (!headers_sent() && session_id() != "") { $res = Session::destroy(); } }