diff --git a/main/document/document.php b/main/document/document.php
index 8dffc09693..22944a271b 100644
--- a/main/document/document.php
+++ b/main/document/document.php
@@ -42,6 +42,7 @@ $lib_path = api_get_path(LIBRARY_PATH);
/* Libraries */
require_once $lib_path . 'fileUpload.lib.php';
require_once $lib_path . 'fileDisplay.lib.php';
+require_once $lib_path . 'fileManage.lib.php';
//require_once $lib_path.'tablesort.lib.php';moved to autoload
api_protect_course_script(true);
@@ -618,7 +619,7 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
}
}
$document_to_move = DocumentManager::get_document_data_by_id($_POST['move_file'], api_get_course_id());
- require_once $lib_path . 'fileManage.lib.php';
+
// Security fix: make sure they can't move files that are not in the document table
if (!empty($document_to_move)) {
@@ -671,20 +672,25 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
api_not_allowed();
}
}
-
if (DocumentManager::check_readonly($_course, api_get_user_id(), $_GET['delete'], '', true)) {
api_not_allowed();
}
}
- require_once api_get_path(LIBRARY_PATH) . 'fileManage.lib.php';
- if (DocumentManager::delete_document($_course, $_GET['delete'], $base_work_dir)) {
- if (isset($_GET['delete_certificate_id']) && $_GET['delete_certificate_id'] == strval(intval($_GET['delete_certificate_id']))) {
- $default_certificate_id = $_GET['delete_certificate_id'];
- DocumentManager::remove_attach_certificate(api_get_course_id(), $default_certificate_id);
+
+ $document_data = DocumentManager::get_document_id($_course, $_GET['delete']);
+ // Check whether the document is in the database
+ if (!empty($document_data)) {
+ if (DocumentManager::delete_document($_course, $_GET['delete'], $base_work_dir)) {
+ if (isset($_GET['delete_certificate_id']) && $_GET['delete_certificate_id'] == strval(intval($_GET['delete_certificate_id']))) {
+ $default_certificate_id = $_GET['delete_certificate_id'];
+ DocumentManager::remove_attach_certificate(api_get_course_id(), $default_certificate_id);
+ }
+ Display::display_confirmation_message(get_lang('DocDeleted'));
+ } else {
+ Display::display_error_message(get_lang('DocDeleteError'));
}
- Display::display_confirmation_message(get_lang('DocDeleted'));
} else {
- Display::display_error_message(get_lang('DocDeleteError'));
+ Display::display_warning_message(get_lang('FileNotFound'));
}
}
diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php
index 5ee30dfc19..5eeef83dc3 100755
--- a/main/inc/lib/document.lib.php
+++ b/main/inc/lib/document.lib.php
@@ -821,6 +821,50 @@ class DocumentManager {
$result = Database::fetch_array(Database::query("SELECT filetype FROM $TABLE_DOCUMENT WHERE c_id = $course_id AND id= $document_id"), 'ASSOC');
return $result['filetype'] == 'folder';
}
+
+ public static function delete_document_from_db($document_id, $course_info = array(), $session_id = 0, $remove_content_from_db = false) {
+ $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
+ $TABLE_ITEMPROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
+
+ //Deleting from the DB
+ $user_id = api_get_user_id();
+
+ if (empty($course_info)) {
+ $course_info = api_get_course_info();
+ }
+ if (empty($session_id)) {
+ $session_id = api_get_session_id();
+ }
+
+ //Soft DB delete
+ api_item_property_update($course_info, TOOL_DOCUMENT, $document_id, 'delete', $user_id, null, null, null, null, $session_id);
+ self::delete_document_from_search_engine($course_info['code'], $document_id);
+ self::unset_document_as_template($document_id, $course_info['code'], $user_id);
+
+ //Hard DB delete
+ if ($remove_content_from_db) {
+ $sql = "DELETE FROM $TABLE_ITEMPROPERTY WHERE c_id = {$course_info['real_id']} AND ref = ".$document_id." AND tool='".TOOL_DOCUMENT."'";
+ Database::query($sql);
+
+ $sql = "DELETE FROM ".$TABLE_DOCUMENT." WHERE c_id = {$course_info['real_id']} AND id = ".$document_id;
+ Database::query($sql);
+
+ self::delete_document_metadata($document_id);
+ }
+ }
+
+ public static function delete_document_metadata($document_id) {
+ //needed to deleted medadata
+ require_once api_get_path(SYS_CODE_PATH).'metadata/md_funcs.php';
+ require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php';
+ $mdStore = new mdstore(true);
+
+ //delete metadata
+ $eid = 'Document'.'.'.$document_id;
+ $mdStore->mds_delete($eid);
+ $mdStore->mds_delete_offspring($eid);
+ }
+
/**
* This deletes a document by changing visibility to 2, renaming it to filename_DELETED_#id
@@ -833,126 +877,98 @@ class DocumentManager {
* @todo now only files/folders in a folder get visibility 2, we should rename them too.
*/
public static function delete_document($_course, $path, $base_work_dir) {
-
- $TABLE_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
- $TABLE_ITEMPROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
-
+ $TABLE_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
+
+ if (empty($path) || empty($base_work_dir)) {
+ return false;
+ }
+
$course_id = $_course['real_id'];
//first, delete the actual document...
$document_id = self :: get_document_id($_course, $path);
+ $document_exists_in_disk = file_exists($base_work_dir.$path);
+
$new_path = $path.'_DELETED_'.$document_id;
$current_session_id = api_get_session_id();
+
+ $file_deleted_from_db = false;
+ $file_deleted_from_disk = false;
+ $file_renamed_from_disk = false;
+
if ($document_id) {
- if (api_get_setting('permanently_remove_deleted_files') == 'true') { //deleted files are *really* deleted
+ self::delete_document_from_db($document_id);
+ //checking
+ $file_exists_in_db = self::get_document_data_by_id($document_id, $_course['code']);
+ $file_deleted_from_db = true;
+ }
+
+ if ($document_exists_in_disk) {
+
+ if (api_get_setting('permanently_remove_deleted_files') == 'true') {
+ //Deleted files are *really* deleted
$what_to_delete_sql = "SELECT id FROM ".$TABLE_DOCUMENT." WHERE c_id = $course_id AND path='".$path."' OR path LIKE BINARY '".$path."/%'";
//get all id's of documents that are deleted
$what_to_delete_result = Database::query($what_to_delete_sql);
if ($what_to_delete_result && Database::num_rows($what_to_delete_result) != 0) {
- //needed to deleted medadata
- require_once api_get_path(SYS_CODE_PATH).'metadata/md_funcs.php';
- require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php';
- $mdStore = new mdstore(true);
-
//delete all item_property entries
while ($row = Database::fetch_array($what_to_delete_result)) {
- //query to delete from item_property table
- //avoid wrong behavior
-
- //$remove_from_item_property_sql = "DELETE FROM ".$TABLE_ITEMPROPERTY." WHERE ref = ".$row['id']." AND tool='".TOOL_DOCUMENT."'";
- api_item_property_update($_course, TOOL_DOCUMENT, $row['id'], 'delete', api_get_user_id(), null, null, null, null, $current_session_id);
-
- //query to delete from document table
- $remove_from_document_sql = "DELETE FROM ".$TABLE_DOCUMENT." WHERE c_id = $course_id AND id = ".$row['id'];
- self::unset_document_as_template($row['id'], $_course, api_get_user_id());
- Database::query($remove_from_document_sql);
-
- //delete metadata
- $eid = 'Document'.'.'.$row['id'];
- $mdStore->mds_delete($eid);
- $mdStore->mds_delete_offspring($eid);
-
+ //query to delete from item_property table (hard way)
+ self::delete_document_from_db($row['id'], $_course, $current_session_id, true);
}
- self::delete_document_from_search_engine(api_get_course_id(), $document_id);
//delete documents, do it like this so metadata get's deleted too
//update_db_info('delete', $path);
//throw it away
- my_delete($base_work_dir.$path);
-
- return true;
- } else {
- return false;
+ my_delete($base_work_dir.$path);
+ $file_deleted_from_disk = true;
}
+ } else {
+ //Set visibility to 2 and rename file/folder to xxx_DELETED_#id (soft delete)
+
+ if (is_file($base_work_dir.$path) || is_dir($base_work_dir.$path)) {
+ if (rename($base_work_dir.$path, $base_work_dir.$new_path)) {
+
+ $sql = "UPDATE $TABLE_DOCUMENT set path='".$new_path."' WHERE c_id = $course_id AND id='".$document_id."'";
+ Database::query($sql);
+
+ $sql = "SELECT id, path FROM $TABLE_DOCUMENT WHERE c_id = $course_id AND path LIKE BINARY '".$path."/%'";
+ $result = Database::query($sql);
+ if ($result && Database::num_rows($result) > 0) {
+ while ($deleted_items = Database::fetch_array($result, 'ASSOC')) {
+ self::delete_document_from_db($deleted_items['id']);
+
+ //Change path of subfolders and documents in database
+ $old_item_path = $deleted_items['path'];
+ $new_item_path = $new_path.substr($old_item_path, strlen($path));
- } else { //set visibility to 2 and rename file/folder to qsdqsd_DELETED_#id
-
- if (api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'delete', api_get_user_id(), null, null, null, null, $current_session_id)) {
- if (is_file($base_work_dir.$path) || is_dir($base_work_dir.$path)) {
- if(rename($base_work_dir.$path, $base_work_dir.$new_path)) {
- self::unset_document_as_template($document_id, api_get_course_id(), api_get_user_id());
- $sql = "UPDATE $TABLE_DOCUMENT set path='".$new_path."' WHERE c_id = $course_id AND id='".$document_id."'";
- if (Database::query($sql)) {
- //if it is a folder it can contain files
- $sql = "SELECT id,path FROM ".$TABLE_DOCUMENT." WHERE c_id = $course_id AND path LIKE BINARY '".$path."/%'";
- $result = Database::query($sql);
- if ($result && Database::num_rows($result) > 0) {
- while ($deleted_items = Database::fetch_array($result, 'ASSOC')) {
- api_item_property_update($_course, TOOL_DOCUMENT, $deleted_items['id'], 'delete', api_get_user_id(),null,null,null,null,$current_session_id);
- //Change path of subfolders and documents in database
- $old_item_path = $deleted_items['path'];
- $new_item_path = $new_path.substr($old_item_path, strlen($path));
- /*
- // Trying to fix this bug FS#2681
- echo $base_work_dir.$old_item_path;
- echo "
";
- echo $base_work_dir.$new_item_path;
- echo "
";
- rename($base_work_dir.$old_item_path, $base_work_dir.$new_item_path);
- */
- self::unset_document_as_template($deleted_items['id'], api_get_course_id(), api_get_user_id());
- $sql = "UPDATE $TABLE_DOCUMENT set path = '".$new_item_path."' WHERE c_id = $course_id AND id = ".$deleted_items['id'];
-
- Database::query($sql);
- }
- }
-
- self::delete_document_from_search_engine(api_get_course_id(), $document_id);
- return true;
+ $sql = "UPDATE $TABLE_DOCUMENT set path = '".$new_item_path."' WHERE c_id = $course_id AND id = ".$deleted_items['id'];
+ Database::query($sql);
}
- } else {
- //Couldn't rename - file permissions problem?
- error_log(__FILE__.' '.__LINE__.': Error renaming '.$base_work_dir.$path.' to '.$base_work_dir.$new_path.'. This is probably due to file permissions',0);
}
-
+ $file_renamed_from_disk = true;
} else {
-
- //echo $base_work_dir.$path;
- //The file or directory isn't there anymore (on the filesystem)
- // This means it has been removed externally. To prevent a
- // blocking error from happening, we drop the related items from the
- // item_property and the document table.
- error_log(__FILE__.' '.__LINE__.': System inconsistency detected. The file or directory '.$base_work_dir.$path.' seems to have been removed from the filesystem independently from the web platform. To restore consistency, the elements using the same path will be removed from the database',0);
-
- $sql = "SELECT id FROM $TABLE_DOCUMENT WHERE c_id = $course_id AND path='".$path."' OR path LIKE BINARY '".$path."/%'";
- $res = Database::query($sql);
-
- self::delete_document_from_search_engine(api_get_course_id(), $document_id);
-
- while ($row = Database::fetch_array($res)) {
- $sqlipd = "DELETE FROM $TABLE_ITEMPROPERTY WHERE c_id = $course_id AND ref = ".$row['id']." AND tool='".TOOL_DOCUMENT."'";
- Database::query($sqlipd);
- self::unset_document_as_template($row['id'],api_get_course_id(), api_get_user_id());
- $sqldd = "DELETE FROM $TABLE_DOCUMENT WHERE c_id = $course_id AND id = ".$row['id'];
- Database::query($sqldd);
- }
+ //Couldn't rename - file permissions problem?
+ error_log(__FILE__.' '.__LINE__.': Error renaming '.$base_work_dir.$path.' to '.$base_work_dir.$new_path.'. This is probably due to file permissions',0);
}
- }
- }
-
+ }
+ }
+ }
+
+ //Checking inconsistency
+ if ($file_deleted_from_db && $file_deleted_from_disk ||
+ $file_deleted_from_db && $file_renamed_from_disk) {
+ return true;
+ } else {
+ //Something went wrong
+
+ //The file or directory isn't there anymore (on the filesystem)
+ // This means it has been removed externally. To prevent a
+ // blocking error from happening, we drop the related items from the
+ // item_property and the document table.
+ error_log(__FILE__.' '.__LINE__.': System inconsistency detected. The file or directory '.$base_work_dir.$path.' seems to have been removed from the filesystem independently from the web platform. To restore consistency, the elements using the same path will be removed from the database',0);
+ return false;
}
-
- return false;
}
/**
@@ -1066,7 +1082,7 @@ class DocumentManager {
$real_dir = '';
for ($i = 1; $i < $array_len; $i++) {
- $sub_visibility = true;
+ //$sub_visibility = true;
$real_dir .= '/'.$dir_array[$i];
$parent_id = self::get_document_id($course_info, $real_dir);
if (!empty($parent_id)) {