file.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Document download/view script
  5. * @package chamilo.document
  6. */
  7. /**
  8. * Init
  9. */
  10. Use Model\Document;
  11. Use Model\Course;
  12. /**
  13. * Return either
  14. *
  15. * - one document
  16. * - several documents (file and/or folders) zipped together
  17. *
  18. * Used to transfer files to another application through http.
  19. *
  20. * Script parameters:
  21. *
  22. * - id id(s) of the document id=1 or id=1,2,4
  23. * - cidReq course code
  24. *
  25. * Note this script enables key authentication so access with a key token is possible.
  26. *
  27. * @package chamilo.document
  28. * @license see /license.txt
  29. * @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
  30. */
  31. require_once __DIR__ . '/../inc/autoload.inc.php';
  32. KeyAuth::enable();
  33. require_once __DIR__ . '/../inc/global.inc.php';
  34. $has_access = api_protect_course_script();
  35. if (!$has_access) {
  36. exit;
  37. }
  38. session_cache_limiter('none');
  39. $ids = Request::get('id', '');
  40. $ids = $ids ? explode(',', $ids) : array();
  41. $course = Course::current();
  42. /**
  43. * No files requested. We make sure we return 404 error to tell the client
  44. * that the call failed.
  45. */
  46. if (count($ids) == 0 || empty($course)) {
  47. Response::not_found();
  48. }
  49. /**
  50. * One file requested. In this case we return the file itself.
  51. */
  52. if (count($ids) == 1) {
  53. $id = reset($ids);
  54. $doc = Document::get_by_id($course, $id);
  55. if (empty($doc)) {
  56. Response::not_found();
  57. }
  58. if ($doc->is_file()) {
  59. $has_access = $doc->is_accessible();
  60. if (!$has_access) {
  61. Response::not_found();
  62. }
  63. event_download(Uri::here());
  64. DocumentManager::file_send_for_download($doc);
  65. exit;
  66. }
  67. }
  68. /**
  69. * Several files requested. In this case we zip them together.
  70. */
  71. $files = array();
  72. $folders = array();
  73. foreach ($ids as $id) {
  74. $doc = Document::get_by_id($course, $id);
  75. if (!$doc->is_accessible()) {
  76. break;
  77. }
  78. if ($doc->is_file()) {
  79. $files[] = $doc;
  80. }
  81. if ($doc->is_folder()) {
  82. $folders[] = $doc;
  83. }
  84. }
  85. $requested_folders = $folders;
  86. /**
  87. * Note that if a parent folder is hidden children should not be accesible
  88. * even if they are visible. It is therefore not sufficient to check document
  89. * visibility.
  90. */
  91. while ($folders) {
  92. $items = $folders;
  93. $folders = array();
  94. foreach ($items as $item) {
  95. $children = $item->get_children();
  96. foreach ($children as $child) {
  97. if (!$child->is_accessible()) {
  98. break;
  99. }
  100. if ($child->is_file()) {
  101. $files[] = $child;
  102. }
  103. if ($child->is_folder()) {
  104. $folders[] = $child;
  105. }
  106. }
  107. }
  108. }
  109. $folders = $requested_folders;
  110. /**
  111. * Requested files may not be accessible.
  112. */
  113. if (count($files) == 0) {
  114. Response::not_found();
  115. }
  116. $root_dir = '';
  117. $items = array_merge($folders, $files);
  118. foreach ($items as $item) {
  119. $path = $item->get_absolute_path();
  120. $path = realpath($path);
  121. $dir = dirname($path);
  122. if (empty($root_dir) || strlen($root_dir) > strlen($dir)) {
  123. $root_dir = $dir;
  124. }
  125. }
  126. /**
  127. * Zip files together.
  128. */
  129. $temp_zip_path = Chamilo::temp_file('zip');
  130. $zip_folder = new PclZip($temp_zip_path);
  131. foreach ($files as $file) {
  132. if (empty($root_dir)) {
  133. $root_dir = dirname($file);
  134. }
  135. $file = (string) $file;
  136. $zip_folder->add($file, PCLZIP_OPT_REMOVE_PATH, $root_dir);
  137. }
  138. /**
  139. * Send file for download
  140. */
  141. event_download(Uri::here());
  142. DocumentManager::file_send_for_download($temp_zip_path, false, get_lang('Documents') . '.zip');