diff --git a/main/document/document.php b/main/document/document.php index 4c3f07220a..d6cdb81676 100755 --- a/main/document/document.php +++ b/main/document/document.php @@ -27,16 +27,15 @@ * @package chamilo.document */ -use ChamiloSession as Session; - require_once '../inc/global.inc.php'; + $current_course_tool = TOOL_DOCUMENT; $this_section = SECTION_COURSES; $to_user_id = null; $parent_id = null; $lib_path = api_get_path(LIBRARY_PATH); - +$actionsRight = ''; api_protect_course_script(true); api_protect_course_group(GroupManager::GROUP_TOOL_DOCUMENTS); @@ -1648,7 +1647,7 @@ if (api_is_allowed_to_edit(null, true)) { api_get_path(WEB_CODE_PATH).'document/document_quota.php?'.api_get_cidreq() ); } -$actionsRight = ''; + if (!$is_certificate_mode) { /* BUILD SEARCH FORM */ $form = new FormValidator( @@ -1759,7 +1758,6 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) { $invisibility_span_close; // Last edit date - $last_edit_date = api_get_local_time($document_data['lastedit_date']); $display_date = date_to_str_ago($last_edit_date). '
'.$last_edit_date."
"; @@ -1842,6 +1840,17 @@ if (!is_null($documentAndFolders)) { } } + +if (api_is_platform_admin()) { + if (api_get_configuration_value('document_manage_deleted_files')) { + $actionsLeft .= Display::url( + get_lang('Recycle'), + api_get_path(WEB_CODE_PATH).'document/recycle.php?'.api_get_cidreq(), + array('class' => 'btn btn-default') + ); + } +} + if (!empty($moveTo)) { $document_id = DocumentManager::get_document_id($courseInfo, $moveTo); } diff --git a/main/document/recycle.php b/main/document/recycle.php new file mode 100644 index 0000000000..281bb55e7c --- /dev/null +++ b/main/document/recycle.php @@ -0,0 +1,65 @@ + 'btn btn-default'] +); + +$actions .= Display::url( + get_lang('DeleteAll'), + api_get_self().'?'.api_get_cidreq().'&action=delete_all', + ['class' => 'btn btn-danger'] +); + +$action = isset($_GET['action']) ? $_GET['action'] : ''; +$id = isset($_GET['id']) ? intval($_GET['id']) : ''; +$currentUrl = api_get_self().'?'.api_get_cidreq(); + +switch ($action) { + case 'delete': + DocumentManager::purgeDocument($id, $courseInfo, $sessionId); + Display::addFlash(Display::return_message(get_lang('Deleted'))); + header('Location: '.$currentUrl); + exit; + break; + case 'delete_all': + DocumentManager::purgeDocuments($courseInfo, $sessionId); + Display::addFlash(Display::return_message(get_lang('Deleted'))); + header('Location: '.$currentUrl); + exit; + break; + case 'download': + DocumentManager::downloadDeletedDocument($id, $courseInfo, $sessionId); + break; + case 'download_all': + DocumentManager::downloadAllDeletedDocument($courseInfo, $sessionId); + break; +} + +$interbreadcrumb[] = array( + "url" => api_get_path(WEB_CODE_PATH).'document/document.php?'.api_get_cidreq(), + "name" => get_lang('Documents'), +); +$template = new Template(get_lang('DeletedDocuments')); +$template->assign('files', $files); +$template->assign('actions', $actions); +$template->assign('web_cid_query', api_get_cidreq()); + +$content = $template->fetch('default/document/recycle.tpl'); +$template->assign('content', $content); +$template->display_one_col_template(); + diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php index c7c4e43241..6941c81a4d 100755 --- a/main/inc/lib/document.lib.php +++ b/main/inc/lib/document.lib.php @@ -5951,7 +5951,7 @@ class DocumentManager /** * Check if the file name or folder searched exist - * @return return bool Return true when exist + * @return bool Return true when exist */ public static function search_keyword($document_name, $keyword) { @@ -6029,5 +6029,154 @@ class DocumentManager return $result; } + /** + * @param array $courseInfo + * @param int $sessionId + * + * @return array + */ + public static function getDeletedDocuments($courseInfo, $sessionId = 0) + { + $table = Database::get_course_table(TABLE_DOCUMENT); + $courseId = $courseInfo['real_id']; + $sessionCondition = api_get_session_condition($sessionId); + $sql = "SELECT * FROM $table + WHERE + path LIKE '%DELETED%' AND + c_id = $courseId + $sessionCondition + ORDER BY path + "; + + $result = Database::query($sql); + $files = array(); + while ($document = Database::fetch_array($result, 'ASSOC')) { + $files[] = $document; + } + + return $files; + } + + /** + * @param int $id + * @param array $courseInfo + * @param int $sessionId + * + * @return array + */ + public static function getDeletedDocument($id, $courseInfo, $sessionId = 0) + { + if (empty($courseInfo)) { + return false; + } + + $table = Database::get_course_table(TABLE_DOCUMENT); + $courseId = $courseInfo['real_id']; + $sessionCondition = api_get_session_condition($sessionId); + $sql = "SELECT * FROM $table + WHERE + path LIKE '%DELETED%' AND + id = $id AND + c_id = $courseId + $sessionCondition + LIMIT 1 + "; + $result = Database::query($sql); + if (Database::num_rows($result)) { + $result = Database::fetch_array($result, 'ASSOC'); + + return $result; + } + + return array(); + } + + /** + * @param int $id + * @param array $courseInfo + * @param int $sessionId + * @return bool + */ + public static function purgeDocument($id, $courseInfo, $sessionId = 0) + { + $document = self::getDeletedDocument($id, $courseInfo, $sessionId); + if (!empty($document)) { + $path = $document['path']; + $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document/'; + my_delete($coursePath.$path); + // Hard delete. + self::deleteDocumentFromDb($id, $courseInfo, $sessionId, true); + + return true; + } + return false; + } + + /** + * @param array $courseInfo + * @param int $sessionId + */ + public static function purgeDocuments($courseInfo, $sessionId) + { + $files = self::getDeletedDocuments($courseInfo, $sessionId); + foreach ($files as $file) { + self::purgeDocument($file['id'], $courseInfo, $sessionId); + } + } + /** + * @param int $id + * @param array $courseInfo + * @param int $sessionId + * @return bool + */ + public static function downloadDeletedDocument($id, $courseInfo, $sessionId) + { + $document = self::getDeletedDocument($id, $courseInfo, $sessionId); + if (!empty($document)) { + $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document/'; + + if (Security::check_abs_path($coursePath.$document['path'], $coursePath)) { + self::file_send_for_download($coursePath.$document['path']); + exit; + } + } + } + + /** + * @param array $courseInfo + * @param int $sessionId + * + * @return bool + */ + public static function downloadAllDeletedDocument($courseInfo, $sessionId) + { + // Zip library for creation of the zip file. + require api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php'; + + $files = self::getDeletedDocuments($courseInfo, $sessionId); + + if (empty($files)) { + return false; + } + + $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document'; + + // Creating a ZIP file. + $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip"; + $zip = new PclZip($tempZipFile); + foreach ($files as $file) { + $zip->add( + $coursePath.$file['path'], + PCLZIP_OPT_REMOVE_PATH, + $coursePath + ); + } + + if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) { + DocumentManager::file_send_for_download($tempZipFile, true); + @unlink($tempZipFile); + exit; + } + } } diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 38934b1e64..f11fe7b38a 100755 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -226,3 +226,5 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE; //$_configuration['courses_list_session_title_link'] = 1; // Fix embedded videos inside lps, adding an optional popup //$_configuration['lp_fix_embed_content'] = false; +// Manage deleted files marked with "DELETED" (by course and only by allowed by admin) +//$_configuration['document_manage_deleted_files'] = false; diff --git a/main/template/default/document/recycle.tpl b/main/template/default/document/recycle.tpl new file mode 100644 index 0000000000..fcbf41fc76 --- /dev/null +++ b/main/template/default/document/recycle.tpl @@ -0,0 +1,48 @@ +{% macro bytesToSize(bytes) %} +{% spaceless %} +{% set kilobyte = 1024 %} +{% set megabyte = kilobyte * 1024 %} +{% set gigabyte = megabyte * 1024 %} +{% set terabyte = gigabyte * 1024 %} + +{% if bytes < kilobyte %} +{{ bytes ~ ' B' }} +{% elseif bytes < megabyte %} +{{ (bytes / kilobyte)|number_format(2, '.') ~ ' KB' }} +{% elseif bytes < gigabyte %} +{{ (bytes / megabyte)|number_format(2, '.') ~ ' MB' }} +{% elseif bytes < terabyte %} +{{ (bytes / gigabyte)|number_format(2, '.') ~ ' GB' }} +{% else %} +{{ (bytes / terabyte)|number_format(2, '.') ~ ' TB' }} +{% endif %} +{% endspaceless %} +{% endmacro %} + +{% if files %} + + + + + + + {% for file in files %} + + + + + + + {% endfor %} +
{{ 'Path' | get_lang }}{{ 'Size' | get_lang }}{{ 'Actions' | get_lang }}
+ {{ file.path }} + + {{ _self.bytesToSize(file.size) }} + + {{ 'Download' | get_lang }} + {{ 'Delete' | get_lang }} +
+{% else %} + {{ 'NoData' | get_lang }} +{% endif %} +