file.php 3.4 KB

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