dropbox_download.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <?php
  2. /*
  3. ==============================================================================
  4. Dokeos - elearning and course management software
  5. Copyright (c) 2006 Dokeos S.A.
  6. Copyright (c) 2006 Ghent University (UGent)
  7. Copyright (c) various contributors
  8. For a full list of contributors, see "credits.txt".
  9. The full license can be read in "license.txt".
  10. This program is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU General Public License
  12. as published by the Free Software Foundation; either version 2
  13. of the License, or (at your option) any later version.
  14. See the GNU General Public License for more details.
  15. Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
  16. Mail: info@dokeos.com
  17. ==============================================================================
  18. */
  19. /*
  20. ==============================================================================
  21. INIT SECTION
  22. ==============================================================================
  23. */
  24. // we cannot use dropbox_init.inc.php because this one already outputs data.
  25. //name of langfile
  26. // name of the language file that needs to be included
  27. $language_file = "dropbox";
  28. // including the basic Dokeos initialisation file
  29. require("../inc/global.inc.php");
  30. // the dropbox configuration parameters
  31. include_once('dropbox_config.inc.php');
  32. // the dropbox sanity files (adds a new table and some new fields)
  33. include_once('dropbox_sanity.inc.php');
  34. // the dropbox file that contains additional functions
  35. include_once('dropbox_functions.inc.php');
  36. // the dropbox class
  37. require_once( "dropbox_class.inc.php");
  38. //
  39. include_once(api_get_path(LIBRARY_PATH).'/document.lib.php');
  40. /*
  41. ==============================================================================
  42. DOWNLOAD A FOLDER
  43. ==============================================================================
  44. */
  45. if ( isset($_GET['cat_id']) AND is_numeric($_GET['cat_id']) AND $_GET['action']=='downloadcategory' AND isset($_GET['sent_received']) )
  46. {
  47. // step 1: constructingd' the sql statement. Due to the nature off the classes of the dropbox the categories for sent files are stored in the table
  48. // dropbox_file while the categories for the received files are stored in dropbox_post. It would have been more elegant if these could be stored
  49. // in dropbox_person (which stores the link file-person)
  50. // Therefore we have to create to separate sql statements to find which files are in the categorie (depending if we zip-download a sent category or a
  51. // received category)
  52. if ($_GET['sent_received']=='sent')
  53. {
  54. // here we also incorporate the person table to make sure that deleted sent documents are not included.
  55. $sql="SELECT DISTINCT file.id, file.filename, file.title FROM `".$dropbox_cnf["fileTbl"]."` file, `".$dropbox_cnf["personTbl"]."` person
  56. WHERE file.uploader_id='".mysql_real_escape_string($_user['user_id'])."'
  57. AND file.cat_id='".mysql_real_escape_string($_GET['cat_id'])."'
  58. AND person.user_id='".mysql_real_escape_string($_user['user_id'])."'
  59. AND person.file_id=file.id
  60. " ;
  61. }
  62. if ($_GET['sent_received']=='received')
  63. {
  64. $sql="SELECT DISTINCT file.id, file.filename, file.title FROM `".$dropbox_cnf["fileTbl"]."` file, `".$dropbox_cnf["personTbl"]."` person, `".$dropbox_cnf["postTbl"]."` post
  65. WHERE post.cat_id='".mysql_real_escape_string($_GET['cat_id'])."'
  66. AND person.user_id='".mysql_real_escape_string($_user['user_id'])."'
  67. AND person.file_id=file.id
  68. AND post.file_id=file.id
  69. " ;
  70. }
  71. $result=api_sql_query($sql,__FILE__,__LINE__);
  72. while ($row=mysql_fetch_array($result))
  73. {
  74. $files_to_download[]=$row['id'];
  75. }
  76. if (!is_array($files_to_download) OR empty($files_to_download))
  77. {
  78. header ("location: index.php?view=".$_GET['sent_received']."&error=ErrorNoFilesInFolder");
  79. exit;
  80. }
  81. zip_download($files_to_download);
  82. exit;
  83. }
  84. /*
  85. ==============================================================================
  86. DOWNLOAD A FILE
  87. ==============================================================================
  88. */
  89. /*
  90. ------------------------------------------------------------------------------
  91. AUTHORIZATION
  92. ------------------------------------------------------------------------------
  93. */
  94. // Check if the id makes sense
  95. if ( ! isset( $_GET['id']) || ! is_numeric( $_GET['id']))
  96. {
  97. Display::display_header($nameTools,"Dropbox");
  98. Display :: display_error_message(get_lang('Error'));
  99. Display::display_footer();
  100. exit;
  101. }
  102. // Check if the user is allowed to download the file
  103. $allowed_to_download=false;
  104. // Check if the user has sent or received the file.
  105. $sql="SELECT * FROM `".$dropbox_cnf["personTbl"]."` WHERE file_id='".mysql_real_escape_string($_GET['id'])."' AND user_id='".mysql_real_escape_string($_user['user_id'])."'";
  106. $result=api_sql_query($sql);
  107. if (mysql_num_rows($result)>0)
  108. {
  109. $allowed_to_download=true;
  110. }
  111. /*
  112. ------------------------------------------------------------------------------
  113. ERROR IF NOT ALLOWED TO DOWNLOAD
  114. ------------------------------------------------------------------------------
  115. */
  116. if (!$allowed_to_download)
  117. {
  118. Display::display_header($nameTools,"Dropbox");
  119. Display :: display_error_message(get_lang('YouAreNotAllowedToDownloadThisFile'));
  120. Display::display_footer();
  121. exit;
  122. }
  123. /*
  124. ------------------------------------------------------------------------------
  125. DOWNLOAD THE FILE
  126. ------------------------------------------------------------------------------
  127. */
  128. // the user is allowed to download the file
  129. else
  130. {
  131. $_SESSION['_seen'][$_course['id']][TOOL_DROPBOX][]=$_GET['id'];
  132. $work = new Dropbox_work($_GET['id']);
  133. $path = dropbox_cnf("sysPath") . "/" . $work -> filename; //path to file as stored on server
  134. $file = $work->title;
  135. require_once(api_get_path(LIBRARY_PATH) . '/document.lib.php');
  136. $mimetype = DocumentManager::file_get_mime_type(TRUE);
  137. $fileparts = explode( '.', $file);
  138. $filepartscount = count( $fileparts);
  139. if ( ( $filepartscount > 1) && isset( $mimetype[$fileparts [$filepartscount - 1]]) && $_GET['action']<>'download')
  140. {
  141. // give hint to browser about filetype
  142. header( "Content-type: " . $mimetype[$fileparts [$filepartscount - 1]] . "\n");
  143. }
  144. else
  145. {
  146. //no information about filetype: force a download dialog window in browser
  147. header( "Content-type: application/octet-stream\n");
  148. }
  149. if(!in_array($fileparts [$filepartscount - 1],array('doc','xls','ppt','pps','sxw','sxc','sxi')))
  150. {
  151. header('Content-Disposition: inline; filename='.$file); // bugs with open office
  152. }
  153. else
  154. {
  155. header('Content-Disposition: attachment; filename='.$file);
  156. }
  157. /**
  158. * Note that if you use these two headers from a previous example:
  159. * header('Cache-Control: no-cache, must-revalidate');
  160. * header('Pragma: no-cache');
  161. * before sending a file to the browser, the "Open" option on Internet Explorer's file download dialog will not work properly. If the user clicks "Open" instead of "Save," the target application will open an empty file, because the downloaded file was not cached. The user will have to save the file to their hard drive in order to use it.
  162. * Make sure to leave these headers out if you'd like your visitors to be able to use IE's "Open" option.
  163. */
  164. header( "Pragma: \n");
  165. header( "Cache-Control: \n");
  166. header( "Cache-Control: public\n"); // IE cannot download from sessions without a cache
  167. /*if ( isset( $_SERVER["HTTPS"]))
  168. {
  169. /**
  170. * We need to set the following headers to make downloads work using IE in HTTPS mode.
  171. *
  172. //header( "Pragma: ");
  173. //header( "Cache-Control: ");
  174. header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n");
  175. header( "Last-Modified: " . gmdate( "D, d M Y H:i:s") . " GMT\n");
  176. header( "Cache-Control: no-store, no-cache, must-revalidate\n"); // HTTP/1.1
  177. header( "Cache-Control: post-check=0, pre-check=0\n", false);
  178. }*/
  179. header( "Content-Description: " . trim( htmlentities( $file)) . "\n");
  180. header( "Content-Transfer-Encoding: binary\n");
  181. header( "Content-Length: " . filesize( $path)."\n" );
  182. $fp = fopen( $path, "rb");
  183. fpassthru( $fp);
  184. exit();
  185. }
  186. // $Id: dropbox_download.php,v 1.10 2005/05/19 14:41:30 renehaentjens Exp $
  187. /*
  188. ==============================================================================
  189. Dokeos - elearning and course management software
  190. Copyright (c) 2004 Dokeos S.A.
  191. Copyright (c) 2003 University of Ghent (UGent)
  192. Copyright (c) 2001 Universite catholique de Louvain (UCL)
  193. Copyright (c) Jan Bols
  194. Copyright (c) Rene Haentjens
  195. For a full list of contributors, see "credits.txt".
  196. The full license can be read in "license.txt".
  197. This program is free software; you can redistribute it and/or
  198. modify it under the terms of the GNU General Public License
  199. as published by the Free Software Foundation; either version 2
  200. of the License, or (at your option) any later version.
  201. See the GNU General Public License for more details.
  202. Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
  203. ==============================================================================
  204. */
  205. /**
  206. ==============================================================================
  207. * Dropbox module for Claroline
  208. * handles downloads of files. Direct downloading is prevented because of an .htaccess file in the
  209. * dropbox directory. So everything goes through this script.
  210. *
  211. * 1. Initialising vars
  212. * 2. Authorisation
  213. * 3. Sanity check of get data & file
  214. * 4. Send headers
  215. * 5. Send file
  216. *
  217. *
  218. * NOTE :
  219. * When testing this with PHP4.0.4 on WinXP and Apache2 there were problems with downloading in IE6
  220. * After searching the only explanation I could find is a problem with the headers:
  221. *
  222. * HEADERS SENT WITH PHP4.3:
  223. * HTTP/1.1·200·OK(CR)
  224. * (LF)
  225. * Date:·Fri,·12·Sep·2003·19:07:33·GMT(CR)
  226. * (LF)
  227. * Server:·Apache/2.0.47·(Win32)·PHP/4.3.3(CR)
  228. * (LF)
  229. * X-Powered-By:·PHP/4.3.3(CR)
  230. * (LF)
  231. * Set-Cookie:·PHPSESSID=06880edcc8363be3f60929576fc1bc6e;·path=/(CR)
  232. * (LF)
  233. * Expires:·Thu,·19·Nov·1981·08:52:00·GMT(CR)
  234. * (LF)
  235. * Cache-Control:·public(CR)
  236. * (LF)
  237. * Pragma:·(CR)
  238. * (LF)
  239. * Content-Transfer-Encoding:·binary(CR)
  240. * (LF)
  241. * Content-Disposition:·attachment;·filename=SV-262E4.png(CR)
  242. * (LF)
  243. * Content-Length:·92178(CR)
  244. * (LF)
  245. * Connection:·close(CR)
  246. * (LF)
  247. * Content-Type:·application/octet-stream(CR)
  248. * (LF)
  249. * (CR)
  250. * (LF)
  251. *
  252. * HEADERS SENT WITH PHP4.0.4:
  253. * HTTP/1.1·200·OK(CR)
  254. * (LF)
  255. * Date:·Fri,·12·Sep·2003·18:28:21·GMT(CR)
  256. * (LF)
  257. * Server:·Apache/2.0.47·(Win32)(CR)
  258. * (LF)
  259. * X-Powered-By:·PHP/4.0.4(CR)
  260. * (LF)
  261. * Expires:·Thu,·19·Nov·1981·08:52:00·GMT(CR)
  262. * (LF)
  263. * Cache-Control:·no-store,·no-cache,·must-revalidate,·post-check=0,·pre-check=0,·,·public(CR)
  264. * (LF)
  265. * Pragma:·no-cache,·(CR)
  266. * (LF)
  267. * Content-Disposition:·attachment;·filename=SV-262E4.png(CR)
  268. * (LF)
  269. * Content-Transfer-Encoding:·binary(CR)
  270. * (LF)
  271. * Set-Cookie:·PHPSESSID=0a5b1c1b9d5e3b474fef359ee55e82d0;·path=/(CR)
  272. * (LF)
  273. * Content-Length:·92178(CR)
  274. * (LF)
  275. * Connection:·close(CR)
  276. * (LF)
  277. * Content-Type:·application/octet-stream(CR)
  278. * (LF)
  279. * (CR)
  280. * (LF)
  281. *
  282. * As you can see the there is a difference in the Cache-Control directive. I suspect that this
  283. * explains the problem. Also take a look at http://bugs.php.net/bug.php?id=16458.
  284. *
  285. * @version 1.21
  286. * @copyright 2004-2005
  287. * @author Jan Bols <jan@ivpv.UGent.be>, main programmer
  288. * @author René Haentjens <rene.haentjens@UGent.be>, several contributions (see RH)
  289. * @author Roan Embrechts, virtual course support
  290. *
  291. * @package dokeos.dropbox
  292. ==============================================================================
  293. */
  294. /*
  295. ==============================================================================
  296. INITIALISING VARIABLES
  297. ==============================================================================
  298. */
  299. require_once( "dropbox_init.inc.php"); //only call init1 because init2 outputs data
  300. require_once( "dropbox_class.inc.php");
  301. /*
  302. ==============================================================================
  303. AUTHORISATION SECTION
  304. ==============================================================================
  305. */
  306. if ( !isset( $_user['user_id']) || !$is_course_member )
  307. {
  308. require_once( "dropbox_init2.inc.php");
  309. exit( );
  310. }
  311. if ($_GET['mailing']) // RH: Mailing detail window call
  312. getUserOwningThisMailing($_GET['mailing'], $_user['user_id'], '500'); // RH or die
  313. /*
  314. ==============================================================================
  315. SANITY CHECKS OF GET DATA & FILE
  316. ==============================================================================
  317. */
  318. if ( ! isset( $_GET['id']) || ! is_numeric( $_GET['id'])) die(dropbox_lang("generalError")." (code 501)");
  319. $work = new Dropbox_work($_GET['id']);
  320. $path = dropbox_cnf("sysPath") . "/" . $work -> filename; //path to file as stored on server
  321. $file = $work->title;
  322. // check that this file exists and that it doesn't include any special characters
  323. //if ( !is_file( $path) || ! eregi( '^[A-Z0-9_\-][A-Z0-9._\-]*$', $file))
  324. if ( !is_file( $path))
  325. {
  326. die(dropbox_lang("generalError")." (code 504)");
  327. }
  328. /*
  329. ==============================================================================
  330. SEND HEADERS
  331. ==============================================================================
  332. */
  333. require_once(api_get_path(LIBRARY_PATH) . '/document.lib.php');
  334. $mimetype = DocumentManager::file_get_mime_type(TRUE);
  335. $fileparts = explode( '.', $file);
  336. $filepartscount = count( $fileparts);
  337. if ( ( $filepartscount > 1) && isset( $mimetype[$fileparts [$filepartscount - 1]]))
  338. {
  339. // give hint to browser about filetype
  340. header( "Content-type: " . $mimetype[$fileparts [$filepartscount - 1]] . "\n");
  341. }
  342. else
  343. {
  344. //no information about filetype: force a download dialog window in browser
  345. header( "Content-type: application/octet-stream\n");
  346. }
  347. if(!in_array($fileparts [$filepartscount - 1],array('doc','xls','ppt','pps','sxw','sxc','sxi')))
  348. {
  349. header('Content-Disposition: inline; filename='.$file); // bugs with open office
  350. }
  351. else
  352. {
  353. header('Content-Disposition: attachment; filename='.$file);
  354. }
  355. /**
  356. * Note that if you use these two headers from a previous example:
  357. * header('Cache-Control: no-cache, must-revalidate');
  358. * header('Pragma: no-cache');
  359. * before sending a file to the browser, the "Open" option on Internet Explorer's file download dialog will not work properly. If the user clicks "Open" instead of "Save," the target application will open an empty file, because the downloaded file was not cached. The user will have to save the file to their hard drive in order to use it.
  360. * Make sure to leave these headers out if you'd like your visitors to be able to use IE's "Open" option.
  361. */
  362. header( "Pragma: \n");
  363. header( "Cache-Control: \n");
  364. header( "Cache-Control: public\n"); // IE cannot download from sessions without a cache
  365. /*if ( isset( $_SERVER["HTTPS"]))
  366. {
  367. /**
  368. * We need to set the following headers to make downloads work using IE in HTTPS mode.
  369. *
  370. //header( "Pragma: ");
  371. //header( "Cache-Control: ");
  372. header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n");
  373. header( "Last-Modified: " . gmdate( "D, d M Y H:i:s") . " GMT\n");
  374. header( "Cache-Control: no-store, no-cache, must-revalidate\n"); // HTTP/1.1
  375. header( "Cache-Control: post-check=0, pre-check=0\n", false);
  376. }*/
  377. header( "Content-Description: " . trim( htmlentities( $file)) . "\n");
  378. header( "Content-Transfer-Encoding: binary\n");
  379. header( "Content-Length: " . filesize( $path)."\n" );
  380. /*
  381. ==============================================================================
  382. SEND FILE
  383. ==============================================================================
  384. */
  385. $fp = fopen( $path, "rb");
  386. fpassthru( $fp);
  387. exit( );
  388. /**
  389. * Found a workaround to another headache that just cropped up tonight. Apparently Opera 6.1 on Linux (unsure of other versions/platforms) has problems downloading files using the above methods if you have enabled compression via zlib.output_compression in php.ini.
  390. * It seems that Opera sees that the actual transfer size is less than the size in the "Content-length" header for the download and decides that the transfer was incomplete or corrupted. It then either continuously retries the download or else leaves you with a corrupted file.
  391. * Solution: Make sure your download script/section is off in its own directory. and add the following to your .htaccess file for that directory:
  392. * php_flag zlib.output_compression off
  393. */
  394. ?>