dropbox_functions.inc.php 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * This file contains additional dropbox functions. Initially there were some
  5. * functions in the init files also but I have moved them over
  6. * to one file -- Patrick Cool <patrick.cool@UGent.be>, Ghent University
  7. */
  8. //require_once '../inc/global.inc.php';
  9. $this_section = SECTION_COURSES;
  10. $htmlHeadXtra[] = '<script type="text/javascript">
  11. function setFocus(){
  12. $("#category_title").focus();
  13. }
  14. $(document).ready(function () {
  15. setFocus();
  16. });
  17. </script>';
  18. /**
  19. * This function is a wrapper function for the multiple actions feature.
  20. * @return Mixed If there is a problem, return a string message, otherwise nothing
  21. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  22. * @version march 2006
  23. */
  24. function handle_multiple_actions() {
  25. global $_user, $is_courseAdmin, $is_courseTutor;
  26. // STEP 1: are we performing the actions on the received or on the sent files?
  27. if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'download_received') {
  28. $part = 'received';
  29. } elseif ($_POST['action'] == 'delete_sent' || $_POST['action'] == 'download_sent') {
  30. $part = 'sent';
  31. }
  32. // STEP 2: at least one file has to be selected. If not we return an error message
  33. foreach ($_POST as $key => $value) {
  34. if (strstr($value, $part.'_') AND $key != 'view_received_category' AND $key != 'view_sent_category') {
  35. $checked_files = true;
  36. $checked_file_ids[] = intval(substr($value, strrpos($value, '_')));
  37. }
  38. }
  39. $checked_file_ids = $_POST['id'];
  40. if (!is_array($checked_file_ids) || count($checked_file_ids) == 0) {
  41. return get_lang('CheckAtLeastOneFile');
  42. }
  43. // STEP 3A: deleting
  44. if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'delete_sent') {
  45. $dropboxfile = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
  46. foreach ($checked_file_ids as $key => $value) {
  47. if ($_GET['view'] == 'received') {
  48. $dropboxfile->deleteReceivedWork($value);
  49. $message = get_lang('ReceivedFileDeleted');
  50. }
  51. if ($_GET['view'] == 'sent' OR empty($_GET['view'])) {
  52. $dropboxfile->deleteSentWork($value);
  53. $message = get_lang('SentFileDeleted');
  54. }
  55. }
  56. return $message;
  57. }
  58. // STEP 3B: giving comment
  59. if ($_POST['actions'] == 'comment') {
  60. // This has not been implemented.
  61. // The idea was that it would be possible to write the same feedback for the selected documents.
  62. }
  63. // STEP 3C: moving
  64. if (strstr($_POST['action'], 'move_')) {
  65. // check move_received_n or move_sent_n command
  66. if (strstr($_POST['action'], 'received')) {
  67. $part = 'received';
  68. $to_cat_id = str_replace('move_received_', '', $_POST['action']);
  69. } else {
  70. $part = 'sent';
  71. $to_cat_id = str_replace('move_sent_', '', $_POST['action']);
  72. }
  73. foreach ($checked_file_ids as $key => $value) {
  74. //var_dump($value);
  75. //var_dump($to_cat_id);
  76. //var_dump($part);
  77. store_move($value, $to_cat_id, $part);
  78. }
  79. return get_lang('FilesMoved');
  80. }
  81. // STEP 3D: downloading
  82. if ($_POST['action'] == 'download_sent' || $_POST['action'] == 'download_received') {
  83. zip_download($checked_file_ids);
  84. }
  85. }
  86. /**
  87. * This function deletes a dropbox category
  88. *
  89. * @todo give the user the possibility what needs to be done with the files in this category: move them to the root, download them as a zip, delete them
  90. *
  91. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  92. * @version march 2006
  93. */
  94. function delete_category($action, $id) {
  95. global $dropbox_cnf;
  96. global $_user, $is_courseAdmin, $is_courseTutor;
  97. // an additional check that might not be necessary
  98. if ($action == 'deletereceivedcategory') {
  99. $sentreceived = 'received';
  100. $entries_table = $dropbox_cnf['tbl_post'];
  101. $id_field = 'file_id';
  102. $return_message = get_lang('ReceivedCatgoryDeleted');
  103. } elseif ($action == 'deletesentcategory') {
  104. $sentreceived = 'sent';
  105. $entries_table = $dropbox_cnf['tbl_file'];
  106. $id_field = 'id';
  107. $return_message = get_lang('SentCatgoryDeleted');
  108. } else {
  109. return get_lang('Error');
  110. }
  111. // step 1: delete the category
  112. $sql = "DELETE FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."' AND $sentreceived='1'";
  113. $result = Database::query($sql);
  114. // step 2: delete all the documents in this category
  115. $sql = "SELECT * FROM ".$entries_table." WHERE cat_id='".Database::escape_string($id)."'";
  116. $result = Database::query($sql);
  117. while($row = Database::fetch_array($result)) {
  118. $dropboxfile = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
  119. if ($action == 'deletereceivedcategory') {
  120. $dropboxfile->deleteReceivedWork($row[$id_field]);
  121. }
  122. if ($action == 'deletesentcategory') {
  123. $dropboxfile->deleteSentWork($row[$id_field]);
  124. }
  125. }
  126. return $return_message;
  127. }
  128. /**
  129. * Displays the form to move one individual file to a category
  130. *
  131. * @return html code of the form that appears in a message box.
  132. *
  133. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  134. * @version march 2006
  135. */
  136. function display_move_form($part, $id, $target = array(), $extra_params) {
  137. echo '<div class="row"><div class="form_header">'.get_lang('MoveFileTo').'</div></div>';
  138. echo '<form name="form1" method="post" action="'.api_get_self().'?view_received_category='.Security::remove_XSS($_GET['view_received_category']).'&view_sent_category='.Security::remove_XSS($_GET['view_sent_category']).'&view='.Security::remove_XSS($_GET['view']).'&'.$extra_params.'">';
  139. echo '<input type="hidden" name="id" value="'.Security::remove_XSS($id).'">';
  140. echo '<input type="hidden" name="part" value="'.Security::remove_XSS($part).'">';
  141. echo '
  142. <div class="row">
  143. <div class="label">
  144. <span class="form_required">*</span> '.get_lang('MoveFileTo').'
  145. </div>
  146. <div class="formw">';
  147. echo '<select name="move_target">';
  148. echo '<option value="0">'.get_lang('Root').'</option>';
  149. foreach ($target as $key => $category) {
  150. echo '<option value="'.$category['cat_id'].'">'.$category['cat_name'].'</option>';
  151. }
  152. echo '</select>';
  153. echo ' </div>
  154. </div>';
  155. echo '<div class="row">
  156. <div class="label">
  157. </div>
  158. <div class="formw">
  159. <button class="next" type="submit" name="do_move" value="'.get_lang('Ok').'">'.get_lang('MoveFile').'</button>
  160. </div>
  161. </div>';
  162. echo '</form>';
  163. echo '<div style="clear: both;"></div>';
  164. }
  165. /**
  166. * This function moves a file to a different category
  167. *
  168. * @param $id the id of the file we are moving
  169. * @param $target the id of the folder we are moving to
  170. * @param $part are we moving a received file or a sent file?
  171. *
  172. * @return language string
  173. *
  174. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  175. * @version march 2006
  176. */
  177. function store_move($id, $target, $part)
  178. {
  179. global $_user;
  180. global $dropbox_cnf;
  181. if ((isset($id) AND $id != '') AND (isset($target) AND $target != '') AND (isset($part) AND $part != '')) {
  182. if ($part == 'received') {
  183. $sql = "UPDATE ".$dropbox_cnf["tbl_post"]." SET cat_id='".Database::escape_string($target)."'
  184. WHERE dest_user_id='".Database::escape_string($_user['user_id'])."'
  185. AND file_id='".Database::escape_string($id)."'";
  186. Database::query($sql);
  187. $return_message = get_lang('ReceivedFileMoved');
  188. }
  189. if ($part == 'sent') {
  190. $sql = "UPDATE ".$dropbox_cnf["tbl_file"]." SET cat_id='".Database::escape_string($target)."'
  191. WHERE uploader_id='".Database::escape_string($_user['user_id'])."'
  192. AND id='".Database::escape_string($id)."'";
  193. Database::query($sql);
  194. $return_message = get_lang('SentFileMoved');
  195. }
  196. } else {
  197. $return_message = get_lang('NotMovedError');
  198. }
  199. return $return_message;
  200. }
  201. /**
  202. * This functions displays all teh possible actions that can be performed on multiple files. This is the dropdown list that
  203. * appears below the sortable table of the sent / or received files.
  204. *
  205. * @return html value for the dropdown list
  206. *
  207. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  208. * @version march 2006
  209. */
  210. function display_action_options($part, $categories, $current_category = 0) {
  211. echo '<select name="actions">';
  212. echo '<option value="download">'.get_lang('Download').'</option>';
  213. echo '<option value="delete">'.get_lang('Delete').'</option>';
  214. if (is_array($categories)) {
  215. echo '<optgroup label="'.get_lang('MoveTo').'">';
  216. if ($current_category != 0) {
  217. echo '<option value="move_0">'.get_lang('Root').'</a>';
  218. }
  219. foreach ($categories as $key => $value) {
  220. if ($current_category != $value['cat_id']) {
  221. echo '<option value="move_'.$value['cat_id'].'">'.$value['cat_name'].'</option>';
  222. }
  223. }
  224. echo '</optgroup>';
  225. }
  226. echo '</select>';
  227. echo '<input type="submit" name="do_actions_'.Security::remove_XSS($part).'" value="'.get_lang('Ok').'" />';
  228. }
  229. /**
  230. * this function returns the html code that displays the checkboxes next to the files so that
  231. * multiple actions on one file are possible.
  232. *
  233. * @param $id the unique id of the file
  234. * @param $part are we dealing with a sent or with a received file?
  235. *
  236. * @return html code
  237. *
  238. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  239. * @version march 2006
  240. */
  241. function display_file_checkbox($id, $part) {
  242. if (isset($_GET['selectall'])) {
  243. $checked = 'checked';
  244. }
  245. $return_value = '<input type="checkbox" name="'.Security::remove_XSS($part).'_'.Security::remove_XSS($id).'" value="'.Security::remove_XSS($id).'" '.$checked.' />';
  246. return $return_value;
  247. }
  248. /**
  249. * This function retrieves all the dropbox categories and returns them as an array
  250. *
  251. * @param $filter default '', when we need only the categories of the sent or the received part.
  252. *
  253. * @return array
  254. *
  255. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  256. * @version march 2006
  257. */
  258. function get_dropbox_categories($filter = '') {
  259. global $_user;
  260. global $dropbox_cnf;
  261. $return_array = array();
  262. $session_id = api_get_session_id();
  263. $condition_session = api_get_session_condition($session_id);
  264. $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."' $condition_session";
  265. $result = Database::query($sql);
  266. while ($row = Database::fetch_array($result)) {
  267. if (($filter == 'sent' AND $row['sent'] == 1) OR ($filter == 'received' AND $row['received'] == 1) OR $filter == '') {
  268. $return_array[$row['cat_id']] = $row;
  269. }
  270. }
  271. return $return_array;
  272. }
  273. /**
  274. * This functions stores a new dropboxcategory
  275. *
  276. * @var it might not seem very elegant if you create a category in sent and in received with the same name that you get two entries in the
  277. * dropbox_category table but it is the easiest solution. You get
  278. * cat_name | received | sent | user_id
  279. * test | 1 | 0 | 237
  280. * test | 0 | 1 | 237
  281. * more elegant would be
  282. * test | 1 | 1 | 237
  283. *
  284. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  285. * @version march 2006
  286. */
  287. function store_addcategory() {
  288. global $_user;
  289. global $dropbox_cnf;
  290. // check if the target is valid
  291. if ($_POST['target'] == 'sent') {
  292. $sent = 1;
  293. $received = 0;
  294. } elseif ($_POST['target'] == 'received') {
  295. $sent = 0;
  296. $received = 1;
  297. } else {
  298. return get_lang('Error');
  299. }
  300. // check if the category name is valid
  301. if ($_POST['category_name'] == '') {
  302. return array('type' => 'error', 'message' => get_lang('ErrorPleaseGiveCategoryName'));
  303. }
  304. if (!$_POST['edit_id']) {
  305. $session_id = api_get_session_id();
  306. // step 3a, we check if the category doesn't already exist
  307. $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."' AND cat_name='".Database::escape_string($_POST['category_name'])."' AND received='".$received."' AND sent='$sent' AND session_id='$session_id'";
  308. $result = Database::query($sql);
  309. // step 3b, we add the category if it does not exist yet.
  310. if (Database::num_rows($result) == 0) {
  311. $sql = "INSERT INTO ".$dropbox_cnf['tbl_category']." (cat_name, received, sent, user_id, session_id)
  312. VALUES ('".Database::escape_string($_POST['category_name'])."', '".Database::escape_string($received)."', '".Database::escape_string($sent)."', '".Database::escape_string($_user['user_id'])."',$session_id)";
  313. Database::query($sql);
  314. return array('type' => 'confirmation', 'message' => get_lang('CategoryStored'));
  315. } else {
  316. return array('type' => 'error', 'message' => get_lang('CategoryAlreadyExistsEditIt'));
  317. }
  318. } else {
  319. $sql = "UPDATE ".$dropbox_cnf['tbl_category']." SET cat_name='".Database::escape_string($_POST['category_name'])."', received='".Database::escape_string($received)."' , sent='".Database::escape_string($sent)."'
  320. WHERE user_id='".Database::escape_string($_user['user_id'])."'
  321. AND cat_id='".Database::escape_string($_POST['edit_id'])."'";
  322. Database::query($sql);
  323. return array('type' => 'confirmation', 'message' => get_lang('CategoryModified'));
  324. }
  325. }
  326. /**
  327. * This function displays the form to add a new category.
  328. *
  329. * @param $category_name this parameter is the name of the category (used when no section is selected)
  330. * @param $id this is the id of the category we are editing.
  331. *
  332. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  333. * @version march 2006
  334. */
  335. function display_addcategory_form($category_name = '', $id = '', $action) {
  336. global $dropbox_cnf;
  337. $title = get_lang('AddNewCategory');
  338. if (isset($id) AND $id != '') {
  339. // retrieve the category we are editing
  340. $sql = "SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."'";
  341. $result = Database::query($sql);
  342. $row = Database::fetch_array($result);
  343. if (empty($category_name)) { // after an edit with an error we do not want to return to the original name but the name we already modified. (happens when createinrecievedfiles AND createinsentfiles are not checked)
  344. $category_name = $row['cat_name'];
  345. }
  346. if ($row['received'] == '1') {
  347. $target = 'received';
  348. }
  349. if ($row['sent'] == '1') {
  350. $target = 'sent';
  351. }
  352. $title = get_lang('EditCategory');
  353. }
  354. if ($action == 'addreceivedcategory') {
  355. $target = 'received';
  356. }
  357. if ($action == 'addsentcategory') {
  358. $target = 'sent';
  359. }
  360. if ($action == 'editcategory') {
  361. $text = get_lang('ModifyCategory');
  362. $class = 'save';
  363. } elseif ($action == 'addreceivedcategory' or $action == 'addsentcategory') {
  364. $text = get_lang('CreateCategory');
  365. $class = 'add';
  366. }
  367. echo '<form name="add_new_category" method="post" action="'.api_get_self().'?view="'.Security::remove_XSS($_GET['view']).'">'."\n";
  368. if (isset($id) AND $id != '') {
  369. echo '<input name="edit_id" type="hidden" value="'.Security::remove_XSS($id).'">';
  370. }
  371. echo '<input name="action" type="hidden" value="'.Security::remove_XSS($action).'">';
  372. echo '<input name="target" type="hidden" value="'.$target.'">';
  373. echo '<div class="row"><div class="form_header">'.$title.'</div></div>';
  374. echo ' <div class="row">
  375. <div class="label">
  376. <span class="form_required">*</span> '.get_lang('CategoryName').'
  377. </div>
  378. <div class="formw">';
  379. if ($_POST AND empty($_POST['category_name'])) {
  380. echo '<span class="form_error">'.get_lang('ThisFieldIsRequired').'. '.get_lang('ErrorPleaseGiveCategoryName').'<span><br />';
  381. }
  382. if ($_POST AND !empty($_POST['category_name'])) {
  383. echo '<span class="form_error">'.get_lang('CategoryAlreadyExistsEditIt').'<span><br />';
  384. }
  385. echo ' <input type="text" id="category_title" name="category_name" value="'.Security::remove_XSS($category_name).'" />
  386. </div>
  387. </div>';
  388. echo ' <div class="row">
  389. <div class="label">
  390. </div>
  391. <div class="formw">
  392. <button class="'.$class.'" type="submit" name="StoreCategory">'.$text.'</button>
  393. </div>
  394. </div>';
  395. echo ' <div class="row">
  396. <div class="label">
  397. </div>
  398. <div class="formw">
  399. <span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>
  400. </div>
  401. </div>';
  402. echo '</form>';
  403. echo '<div style="clear: both;"></div>';
  404. }
  405. /**
  406. * this function displays the form to upload a new item to the dropbox.
  407. *
  408. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  409. * @version march 2006
  410. */
  411. function display_add_form() {
  412. global $_user, $is_courseAdmin, $is_courseTutor, $course_info, $origin, $dropbox_unid;
  413. $token = Security::get_token();
  414. $dropbox_person = new Dropbox_Person(api_get_user_id(), $is_courseAdmin, $is_courseTutor);
  415. ?>
  416. <form method="post" action="index.php?view_received_category=<?php echo Security::remove_XSS($_GET['view_received_category']); ?>&view_sent_category=<?php echo Security::remove_XSS($_GET['view_sent_category']); ?>&view=<?php echo Security::remove_XSS($_GET['view']); ?>&<?php echo "origin=$origin"."&".api_get_cidreq(); ?>" enctype="multipart/form-data" onsubmit="javascript: return checkForm(this);">
  417. <div class="row"><div class="form_header"><?php echo get_lang('UploadNewFile'); ?></div></div>
  418. <div class="row">
  419. <div class="label">
  420. <span class="form_required">*</span><?php echo get_lang('UploadFile'); ?>:
  421. </div>
  422. <div class="formw">
  423. <input type="hidden" name="MAX_FILE_SIZE" value='<?php echo dropbox_cnf('maxFilesize'); ?>' />
  424. <input type="file" name="file" size="20" <?php if (dropbox_cnf('allowOverwrite')) echo 'onChange="javascript: checkfile(this.value);"'; ?> />
  425. <input type="hidden" name="dropbox_unid" value="<?php echo $dropbox_unid; ?>" />
  426. <input type="hidden" name="sec_token" value="<?php echo $token; ?>" />
  427. <?php
  428. if ($origin == 'learnpath') {
  429. echo '<input type="hidden" name="origin" value="learnpath" />';
  430. }
  431. ?>
  432. </div>
  433. </div>
  434. <?php
  435. if (dropbox_cnf('allowOverwrite')) {
  436. ?>
  437. <div class="row">
  438. <div class="label">
  439. </div>
  440. <div class="formw">
  441. <input type="checkbox" name="cb_overwrite" id="cb_overwrite" value="true" /><?php echo get_lang('OverwriteFile'); ?>
  442. </div>
  443. </div>
  444. <?php
  445. }
  446. ?>
  447. <div class="row">
  448. <div class="label">
  449. <?php echo get_lang('SendTo'); ?>
  450. </div>
  451. <div class="formw">
  452. <?php
  453. //list of all users in this course and all virtual courses combined with it
  454. if (api_get_session_id()) {
  455. $complete_user_list_for_dropbox = array();
  456. if (api_get_setting('dropbox_allow_student_to_student')=='true' || $_user['status'] != STUDENT) {
  457. $complete_user_list_for_dropbox = CourseManager :: get_user_list_from_course_code($course_info['code'], true, api_get_session_id());
  458. }
  459. $complete_user_list2 = CourseManager::get_coach_list_from_course_code($course_info['code'], api_get_session_id());
  460. $complete_user_list_for_dropbox = array_merge($complete_user_list_for_dropbox, $complete_user_list2);
  461. } else {
  462. if (api_get_setting('dropbox_allow_student_to_student') == 'true' || $_user['status'] != STUDENT) {
  463. $complete_user_list_for_dropbox = CourseManager :: get_user_list_from_course_code($course_info['code'], false, api_get_session_id());
  464. } else {
  465. $complete_user_list_for_dropbox = CourseManager :: get_teacher_list_from_course_code($course_info['code'], false);
  466. }
  467. }
  468. if (!empty($complete_user_list_for_dropbox)) {
  469. foreach ($complete_user_list_for_dropbox as $k => $e) {
  470. $complete_user_list_for_dropbox[$k] = $e + array('lastcommafirst' => api_get_person_name($e['firstname'], $e['lastname']));
  471. }
  472. $complete_user_list_for_dropbox = TableSort::sort_table($complete_user_list_for_dropbox, 'lastcommafirst');
  473. }
  474. ?>
  475. <select name="recipients[]" size="
  476. <?php
  477. if ($dropbox_person -> isCourseTutor || $dropbox_person -> isCourseAdmin) {
  478. echo 10;
  479. } else {
  480. echo 6;
  481. }
  482. ?>" multiple style="width: 350px;">
  483. <?php
  484. /*
  485. Create the options inside the select box:
  486. List all selected users their user id as value and a name string as display
  487. */
  488. $current_user_id = '';
  489. foreach ($complete_user_list_for_dropbox as $current_user) {
  490. if (($dropbox_person -> isCourseTutor
  491. || $dropbox_person -> isCourseAdmin
  492. || dropbox_cnf('allowStudentToStudent')
  493. || $current_user['status'] != 5 // Always allow teachers.
  494. || $current_user['tutor_id'] == 1 // Always allow tutors.
  495. ) && $current_user['user_id'] != $_user['user_id']) { // Don't include yourself.
  496. if ($current_user['user_id'] == $current_user_id) {
  497. continue;
  498. }
  499. $full_name = $current_user['lastcommafirst'];
  500. $current_user_id = $current_user['user_id'];
  501. echo '<option value="user_' . $current_user_id . '">' . $full_name . '</option>';
  502. }
  503. }
  504. /*
  505. * Show groups
  506. */
  507. if (($dropbox_person -> isCourseTutor || $dropbox_person -> isCourseAdmin)
  508. && dropbox_cnf('allowGroup') || dropbox_cnf('allowStudentToStudent')) {
  509. $complete_group_list_for_dropbox = GroupManager::get_group_list(null, dropbox_cnf('courseId'));
  510. if (count($complete_group_list_for_dropbox) > 0) {
  511. foreach ($complete_group_list_for_dropbox as $current_group) {
  512. if ($current_group['number_of_members'] > 0) {
  513. echo '<option value="group_'.$current_group['id'].'">G: '.$current_group['name'].' - '.$current_group['number_of_members'].' '.get_lang('Users').'</option>';
  514. }
  515. }
  516. }
  517. }
  518. if (($dropbox_person -> isCourseTutor || $dropbox_person -> isCourseAdmin) && dropbox_cnf('allowMailing')) {
  519. // echo '<option value="mailing">'.get_lang('MailingInSelect').'</option>';
  520. }
  521. if (dropbox_cnf('allowJustUpload')) {
  522. //echo '<option value="upload">'.get_lang('JustUploadInSelect').'</option>';
  523. echo '<option value="user_'.$_user['user_id'].'">'.get_lang('JustUploadInSelect').'</option>';
  524. }
  525. echo '
  526. </select>
  527. </div>
  528. </div>';
  529. echo '
  530. <div class="row">
  531. <div class="label">
  532. </div>
  533. <div class="formw">
  534. <button type="Submit" class="upload" name="submitWork">'.get_lang('Upload', '').'</button>
  535. </div>
  536. </div>
  537. ';
  538. echo '</form>';
  539. }
  540. /**
  541. * returns username or false if user isn't registered anymore
  542. * @todo check if this function is still necessary. There might be a library function for this.
  543. */
  544. function getUserNameFromId($id) {
  545. global $dropbox_cnf;
  546. $mailingId = $id - dropbox_cnf('mailingIdBase');
  547. if ($mailingId > 0) {
  548. return get_lang('MailingAsUsername', '') . $mailingId;
  549. }
  550. $id = intval($id);
  551. $sql = "SELECT ".(api_is_western_name_order() ? "CONCAT(firstname,' ', lastname)" : "CONCAT(lastname,' ', firstname)")." AS name
  552. FROM " . $dropbox_cnf['tbl_user'] . "
  553. WHERE user_id='$id'";
  554. $result = Database::query($sql);
  555. $res = Database::fetch_array($result);
  556. if (!$res) return false;
  557. return stripslashes($res['name']);
  558. }
  559. /**
  560. * returns loginname or false if user isn't registered anymore
  561. * @todo check if this function is still necessary. There might be a library function for this.
  562. */
  563. function getLoginFromId($id) {
  564. $id = intval($id);
  565. $sql = "SELECT username
  566. FROM " . dropbox_cnf('tbl_user') . "
  567. WHERE user_id='$id'";
  568. $result = Database::query($sql);
  569. $res = Database::fetch_array($result);
  570. if (!$res) return false;
  571. return stripslashes($res['username']);
  572. }
  573. /**
  574. * @return boolean indicating if user with user_id=$user_id is a course member
  575. * @todo eliminate global
  576. * @todo check if this function is still necessary. There might be a library function for this.
  577. */
  578. function isCourseMember($user_id) {
  579. global $_course;
  580. $course_code = $_course['sysCode'];
  581. $is_course_member = CourseManager::is_user_subscribed_in_course($user_id, $course_code, true);
  582. return $is_course_member;
  583. }
  584. /**
  585. * Checks if there are files in the dropbox_file table that aren't used anymore in dropbox_person table.
  586. * If there are, all entries concerning the file are deleted from the db + the file is deleted from the server
  587. */
  588. function removeUnusedFiles() {
  589. // select all files that aren't referenced anymore
  590. $sql = "SELECT DISTINCT f.id, f.filename
  591. FROM " . dropbox_cnf('tbl_file') . " f
  592. LEFT JOIN " . dropbox_cnf('tbl_person') . " p ON f.id = p.file_id
  593. WHERE p.user_id IS NULL";
  594. $result = Database::query($sql);
  595. while ($res = Database::fetch_array($result)) {
  596. //delete the selected files from the post and file tables
  597. $sql = "DELETE FROM " . dropbox_cnf('tbl_post') . " WHERE file_id='" . $res['id'] . "'";
  598. $result1 = Database::query($sql);
  599. $sql = "DELETE FROM " . dropbox_cnf('tbl_file') . " WHERE id='" . $res['id'] . "'";
  600. $result1 = Database::query($sql);
  601. //delete file from server
  602. @unlink( dropbox_cnf('sysPath') . '/' . $res['filename']);
  603. }
  604. }
  605. /**
  606. *
  607. * Mailing zip-file is posted to (dest_user_id = ) mailing pseudo_id
  608. * and is only visible to its uploader (user_id).
  609. *
  610. * Mailing content files have uploader_id == mailing pseudo_id, a normal recipient,
  611. * and are visible initially to recipient and pseudo_id.
  612. *
  613. * @author René Haentjens, Ghent University
  614. *
  615. * @todo check if this function is still necessary.
  616. */
  617. function getUserOwningThisMailing($mailingPseudoId, $owner = 0, $or_die = '') {
  618. global $dropbox_cnf;
  619. $mailingPseudoId = intval($mailingPseudoId);
  620. $sql = "SELECT f.uploader_id
  621. FROM " . $dropbox_cnf['tbl_file'] . " f
  622. LEFT JOIN " . $dropbox_cnf['tbl_post'] . " p ON f.id = p.file_id
  623. WHERE p.dest_user_id = '" . $mailingPseudoId . "'";
  624. $result = Database::query($sql);
  625. if (!($res = Database::fetch_array($result)))
  626. die(get_lang('GeneralError').' (code 901)');
  627. if ($owner == 0) return $res['uploader_id'];
  628. if ($res['uploader_id'] == $owner) return true;
  629. die(get_lang('GeneralError').' (code '.$or_die.')');
  630. }
  631. /**
  632. * @author René Haentjens, Ghent University
  633. * @todo check if this function is still necessary.
  634. */
  635. function removeMoreIfMailing($file_id) {
  636. global $dropbox_cnf;
  637. // when deleting a mailing zip-file (posted to mailingPseudoId):
  638. // 1. the detail window is no longer reachable, so
  639. // for all content files, delete mailingPseudoId from person-table
  640. // 2. finding the owner (getUserOwningThisMailing) is no longer possible, so
  641. // for all content files, replace mailingPseudoId by owner as uploader
  642. $file_id = intval($file_id);
  643. $sql = "SELECT p.dest_user_id
  644. FROM " . $dropbox_cnf['tbl_post'] . " p
  645. WHERE p.file_id = '" . $file_id . "'";
  646. $result = Database::query($sql);
  647. if ($res = Database::fetch_array($result)) {
  648. $mailingPseudoId = $res['dest_user_id'];
  649. if ($mailingPseudoId > dropbox_cnf('mailingIdBase')) {
  650. $sql = "DELETE FROM " . dropbox_cnf('tbl_person') . " WHERE user_id='" . $mailingPseudoId . "'";
  651. $result1 = Database::query($sql);
  652. $sql = "UPDATE " . dropbox_cnf('tbl_file') .
  653. " SET uploader_id='" . api_get_user_id() . "' WHERE uploader_id='" . $mailingPseudoId . "'";
  654. $result1 = Database::query($sql);
  655. }
  656. }
  657. }
  658. /**
  659. * Function that finds a given config setting
  660. *
  661. * @author René Haentjens, Ghent University
  662. */
  663. function dropbox_cnf($variable) {
  664. return $GLOBALS['dropbox_cnf'][$variable];
  665. }
  666. /**
  667. *
  668. */
  669. function store_add_dropbox() {
  670. global $dropbox_cnf;
  671. global $_user;
  672. global $_course;
  673. // Validating the form data
  674. // the author is
  675. /*
  676. if (!isset($_POST['authors'])) {
  677. return get_lang('AuthorFieldCannotBeEmpty');
  678. }
  679. */
  680. // there are no recipients selected
  681. if (!isset($_POST['recipients']) || count( $_POST['recipients']) <= 0) {
  682. return get_lang('YouMustSelectAtLeastOneDestinee');
  683. }
  684. // Check if all the recipients are valid
  685. else {
  686. $thisIsAMailing = false;
  687. $thisIsJustUpload = false;
  688. foreach ($_POST['recipients'] as $rec) {
  689. if ($rec == 'mailing') {
  690. $thisIsAMailing = true;
  691. } elseif ($rec == 'upload') {
  692. $thisIsJustUpload = true;
  693. } elseif (strpos($rec, 'user_') === 0 && !isCourseMember(substr($rec, strlen('user_')))) {
  694. return get_lang('InvalideUserDetected');
  695. } elseif (strpos($rec, 'group_') !== 0 && strpos($rec, 'user_') !== 0) {
  696. return get_lang('InvalideGroupDetected');
  697. }
  698. }
  699. }
  700. // we are doing a mailing but an additional recipient is selected
  701. if ($thisIsAMailing && (count($_POST['recipients']) != 1)) {
  702. return get_lang('MailingSelectNoOther');
  703. }
  704. // we are doing a just upload but an additional recipient is selected.
  705. // note: why can't this be valid? It is like sending a document to yourself AND to a different person (I do this quite often with my e-mails)
  706. if ($thisIsJustUpload && (count($_POST['recipients']) != 1)) {
  707. return get_lang('MailingJustUploadSelectNoOther');
  708. }
  709. if (empty($_FILES['file']['name'])) {
  710. $error = true;
  711. return get_lang('NoFileSpecified');
  712. }
  713. // are we overwriting a previous file or sending a new one
  714. $dropbox_overwrite = false;
  715. if (isset($_POST['cb_overwrite']) && $_POST['cb_overwrite']) {
  716. $dropbox_overwrite = true;
  717. }
  718. // doing the upload
  719. $dropbox_filename = $_FILES['file']['name'];
  720. $dropbox_filesize = $_FILES['file']['size'];
  721. $dropbox_filetype = $_FILES['file']['type'];
  722. $dropbox_filetmpname = $_FILES['file']['tmp_name'];
  723. // check if the filesize does not exceed the allowed size.
  724. if ($dropbox_filesize <= 0 || $dropbox_filesize > $dropbox_cnf['maxFilesize']) {
  725. return get_lang('DropboxFileTooBig'); // TODO: The "too big" message does not fit in the case of uploading zero-sized file.
  726. }
  727. // check if the file is actually uploaded
  728. if (!is_uploaded_file($dropbox_filetmpname)) { // check user fraud : no clean error msg.
  729. return get_lang('TheFileIsNotUploaded');
  730. }
  731. // Try to add an extension to the file if it hasn't got one
  732. $dropbox_filename = add_ext_on_mime($dropbox_filename, $dropbox_filetype);
  733. // Replace dangerous characters
  734. $dropbox_filename = replace_dangerous_char($dropbox_filename);
  735. // Transform any .php file in .phps fo security
  736. $dropbox_filename = php2phps($dropbox_filename);
  737. //filter extension
  738. if (!filter_extension($dropbox_filename)) {
  739. return get_lang('UplUnableToSaveFileFilteredExtension');
  740. }
  741. // set title
  742. $dropbox_title = $dropbox_filename;
  743. // set author
  744. if ($_POST['authors'] == '') {
  745. $_POST['authors'] = getUserNameFromId($_user['user_id']);
  746. }
  747. // note: I think we could better migrate everything from here on to separate functions: store_new_dropbox, store_new_mailing, store_just_upload
  748. if ($dropbox_overwrite) {
  749. $dropbox_person = new Dropbox_Person($_user['user_id'], api_is_course_admin(), api_is_course_tutor());
  750. foreach ($dropbox_person->sentWork as $w) {
  751. if ($w->title == $dropbox_filename) {
  752. if (($w->recipients[0]['id'] > dropbox_cnf('mailingIdBase')) xor $thisIsAMailing) {
  753. return get_lang('MailingNonMailingError');
  754. }
  755. if (($w->recipients[0]['id'] == $_user['user_id']) xor $thisIsJustUpload) {
  756. return get_lang('MailingJustUploadSelectNoOther');
  757. }
  758. $dropbox_filename = $w->filename;
  759. $found = true; // note: do we still need this?
  760. break;
  761. }
  762. }
  763. } else { // rename file to login_filename_uniqueId format
  764. $dropbox_filename = getLoginFromId($_user['user_id']) . "_" . $dropbox_filename . "_".uniqid('');
  765. }
  766. // creating the array that contains all the users who will receive the file
  767. $new_work_recipients = array();
  768. foreach ($_POST['recipients'] as $rec) {
  769. if (strpos($rec, 'user_') === 0) {
  770. $new_work_recipients[] = substr($rec, strlen('user_') );
  771. } elseif (strpos($rec, 'group_') === 0) {
  772. $userList = GroupManager::get_subscribed_users(substr($rec, strlen('group_')));
  773. foreach ($userList as $usr) {
  774. if (!in_array($usr['user_id'], $new_work_recipients) && $usr['user_id'] != $_user['user_id']) {
  775. $new_work_recipients[] = $usr['user_id'];
  776. }
  777. }
  778. }
  779. }
  780. @move_uploaded_file($dropbox_filetmpname, dropbox_cnf('sysPath') . '/' . $dropbox_filename);
  781. $b_send_mail = api_get_course_setting('email_alert_on_new_doc_dropbox');
  782. if ($b_send_mail) {
  783. foreach ($new_work_recipients as $recipient_id) {
  784. require_once api_get_path(LIBRARY_PATH) . 'usermanager.lib.php' ;
  785. $recipent_temp = UserManager :: get_user_info_by_id($recipient_id);
  786. @api_mail(api_get_person_name($recipent_temp['firstname'].' '.$recipent_temp['lastname'], null, PERSON_NAME_EMAIL_ADDRESS), $recipent_temp['email'],
  787. get_lang('NewDropboxFileUploaded'),
  788. get_lang('NewDropboxFileUploadedContent').' '.api_get_path(WEB_CODE_PATH).'dropbox/index.php?cidReq='.$_course['sysCode']."\n\n".api_get_person_name($_user['firstName'], $_user['lastName'], null, PERSON_NAME_EMAIL_ADDRESS)."\n". get_lang('Email') ." : ".$_user['mail'], api_get_person_name($_user['firstName'], $_user['lastName'], null, PERSON_NAME_EMAIL_ADDRESS), $_user['mail']);
  789. }
  790. }
  791. new Dropbox_SentWork( $_user['user_id'], $dropbox_title, $_POST['description'], strip_tags($_POST['authors']), $dropbox_filename, $dropbox_filesize, $new_work_recipients);
  792. Security::clear_token();
  793. return get_lang('FileUploadSucces');
  794. }
  795. /**
  796. * This function displays the firstname and lastname of the user as a link to the user tool.
  797. *
  798. * @see this is the same function as in the new forum, so this probably has to move to a user library.
  799. *
  800. * @todo move this function to the user library (there is a duplicate in work.lib.php)
  801. *
  802. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  803. * @version march 2006
  804. */
  805. function display_user_link_work($user_id, $name = '') {
  806. if ($user_id != 0) {
  807. if (empty($name)) {
  808. $table_user = Database::get_main_table(TABLE_MAIN_USER);
  809. $sql = "SELECT * FROM $table_user WHERE user_id='".Database::escape_string($user_id)."'";
  810. $result = Database::query($sql);
  811. $row = Database::fetch_array($result);
  812. return '<a href="../user/userInfo.php?uInfo='.$row['user_id'].'">'.api_get_person_name($row['firstname'], $row['lastname']).'</a>';
  813. } else {
  814. $user_id = intval($user_id);
  815. return '<a href="../user/userInfo.php?uInfo='.$user_id.'">'.Security::remove_XSS($name).'</a>';
  816. }
  817. } else {
  818. return $name.' ('.get_lang('Anonymous').')';
  819. }
  820. }
  821. /**
  822. * this function transforms the array containing all the feedback into something visually attractive.
  823. *
  824. * @param an array containing all the feedback about the given message.
  825. *
  826. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  827. * @version march 2006
  828. */
  829. function feedback($array) {
  830. foreach ($array as $key => $value) {
  831. $output .= format_feedback($value);
  832. }
  833. $output .= feedback_form();
  834. return $output;
  835. }
  836. /**
  837. * This function returns the html code to display the feedback messages on a given dropbox file
  838. * @param $feedback_array an array that contains all the feedback messages about the given document.
  839. * @return html code
  840. * @todo add the form for adding new comment (if the other party has not deleted it yet).
  841. *
  842. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  843. * @version march 2006
  844. */
  845. function format_feedback($feedback) {
  846. $output .= display_user_link_work($feedback['author_user_id']);
  847. $output .= '&nbsp;&nbsp;'.api_convert_and_format_date($feedback['feedback_date'], DATE_TIME_FORMAT_LONG).'<br />';
  848. $output .= '<div style="padding-top:6px">'.nl2br($feedback['feedback']).'</div><hr size="1" noshade/><br />';
  849. return $output;
  850. }
  851. /**
  852. * this function returns the code for the form for adding a new feedback message to a dropbox file.
  853. * @return html code
  854. *
  855. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  856. * @version march 2006
  857. */
  858. function feedback_form() {
  859. global $dropbox_cnf;
  860. $return = get_lang('AddNewFeedback').'<br />';
  861. // we now check if the other users have not delete this document yet. If this is the case then it is useless to see the
  862. // add feedback since the other users will never get to see the feedback.
  863. $sql = "SELECT * FROM ".$dropbox_cnf['tbl_person']." WHERE file_id = ".intval($_GET['id']);
  864. $result = Database::query($sql);
  865. $number_users_who_see_file = Database::num_rows($result);
  866. if ($number_users_who_see_file > 1) {
  867. $token = Security::get_token();
  868. $return .= '<textarea name="feedback" style="width: 80%; height: 80px;"></textarea>';
  869. $return .= '<input type="hidden" name="sec_token" value="'.$token.'"/>';
  870. $return .= '<br /><button type="submit" class="add" name="store_feedback" value="'.get_lang('Ok').'"
  871. onclick="javascript: document.form_dropbox.attributes.action.value = document.location;">'.get_lang('AddComment').'</button>';
  872. } else {
  873. $return .= get_lang('AllUsersHaveDeletedTheFileAndWillNotSeeFeedback');
  874. }
  875. return $return;
  876. }
  877. /**
  878. * @return a language string (depending on the success or failure.
  879. *
  880. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  881. * @version march 2006
  882. */
  883. function store_feedback() {
  884. global $dropbox_cnf;
  885. if (!is_numeric($_GET['id'])) {
  886. return get_lang('FeedbackError');
  887. }
  888. if (empty($_POST['feedback'])) {
  889. return get_lang('PleaseTypeText');
  890. } else {
  891. $sql="INSERT INTO ".$dropbox_cnf['tbl_feedback']." (file_id, author_user_id, feedback, feedback_date) VALUES
  892. ('".intval($_GET['id'])."','".api_get_user_id()."','".Database::escape_string($_POST['feedback'])."', '".api_get_utc_datetime()."')";
  893. Database::query($sql);
  894. return get_lang('DropboxFeedbackStored');
  895. }
  896. }
  897. /**
  898. * This function downloads all the files of the inputarray into one zip
  899. * @param $array an array containing all the ids of the files that have to be downloaded.
  900. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  901. * @todo consider removing the check if the user has received or sent this file (zip download of a folder already sufficiently checks for this).
  902. * @todo integrate some cleanup function that removes zip files that are older than 2 days
  903. *
  904. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  905. * @version march 2006
  906. */
  907. function zip_download($array) {
  908. global $_course;
  909. global $dropbox_cnf;
  910. global $_user;
  911. global $files;
  912. $sys_course_path = api_get_path(SYS_COURSE_PATH);
  913. // zip library for creation of the zipfile
  914. require api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php';
  915. // place to temporarily stash the zipfiles
  916. $temp_zip_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/';
  917. // create the directory if it does not exist yet.
  918. if (!is_dir($temp_zip_dir)) {
  919. mkdir($temp_zip_dir, api_get_permissions_for_new_directories());
  920. }
  921. cleanup_temp_dropbox();
  922. $files = '';
  923. // note: we also have to add the check if the user has received or sent this file.
  924. $sql = "SELECT distinct file.filename, file.title, file.author, file.description
  925. FROM ".$dropbox_cnf['tbl_file']." file, ".$dropbox_cnf['tbl_person']." person
  926. WHERE file.id IN (".implode(', ',$array).")
  927. AND file.id=person.file_id
  928. AND person.user_id='".$_user['user_id']."'";
  929. $result = Database::query($sql);
  930. while ($row = Database::fetch_array($result)) {
  931. $files[$row['filename']] = array('filename' => $row['filename'],'title' => $row['title'], 'author' => $row['author'], 'description' => $row['description']);
  932. }
  933. //$alternative is a variable that uses an alternative method to create the zip
  934. // because the renaming of the files inside the zip causes error on php5 (unexpected end of archive)
  935. $alternative = true;
  936. if ($alternative) {
  937. zip_download_alternative($files);
  938. exit;
  939. }
  940. // create the zip file
  941. $name = 'dropboxdownload-'.api_get_user_id().'-'.mktime().'.zip';
  942. $temp_zip_file = $temp_zip_dir.'/'.$name;
  943. $zip_folder = new PclZip($temp_zip_file);
  944. foreach ($files as $key => $value) {
  945. // met hernoemen van de files in de zip
  946. $zip_folder->add(api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'], PCLZIP_OPT_REMOVE_PATH, api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox', PCLZIP_CB_PRE_ADD, 'my_pre_add_callback');
  947. // zonder hernoemen van de files in de zip
  948. //$zip_folder->add(api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'],PCLZIP_OPT_REMOVE_PATH, api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox');
  949. }
  950. // create the overview file
  951. $overview_file_content = generate_html_overview($files, array('filename'), array('title'));
  952. $overview_file = $temp_zip_dir.'/overview.html';
  953. $handle = fopen($overview_file, 'w');
  954. fwrite($handle, $overview_file_content);
  955. // send the zip file
  956. DocumentManager::file_send_for_download($temp_zip_file, true, $name);
  957. exit;
  958. }
  959. /**
  960. * This is a callback function to decrypt the files in the zip file to their normal filename (as stored in the database)
  961. * @param $p_event a variable of PCLZip
  962. * @param $p_header a variable of PCLZip
  963. *
  964. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  965. * @version march 2006
  966. */
  967. function my_pre_add_callback($p_event, &$p_header) {
  968. global $files;
  969. $p_header['stored_filename'] = $files[$p_header['stored_filename']]['title'];
  970. return 1;
  971. }
  972. /**
  973. * This function is an alternative zip download. It was added because PCLZip causes problems on PHP5 when using PCLZIP_CB_PRE_ADD and a callback function to rename
  974. * the files inside the zip file (dropbox scrambles the files to prevent
  975. * @todo consider using a htaccess that denies direct access to the file but only allows the php file to access it. This would remove the scrambling requirement
  976. * but it would require additional checks to see if the filename of the uploaded file is not used yet.
  977. * @param $files is an associative array that contains the files that the user wants to download (check to see if the user is allowed to download these files already
  978. * happened so the array is clean!!. The key is the filename on the filesystem. The value is an array that contains both the filename on the filesystem and
  979. * the original filename (that will be used in the zip file)
  980. * @todo when we copy the files there might be two files with the same name. We need a function that (recursively) checks this and changes the name
  981. *
  982. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  983. * @version march 2006
  984. */
  985. function zip_download_alternative($files)
  986. {
  987. global $_course;
  988. global $_user;
  989. $temp_zip_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/';
  990. // Step 2: we copy all the original dropbox files to the temp folder and change their name into the original name
  991. foreach ($files as $key => $value) {
  992. $value['title'] = check_file_name(api_strtolower($value['title']));
  993. $files[$value['filename']]['title'] = $value['title'];
  994. copy(api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'], api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/'.$value['title']);
  995. }
  996. // Step 3: create the zip file and add all the files to it
  997. $temp_zip_file = $temp_zip_dir.'/dropboxdownload-'.api_get_user_id().'-'.mktime().'.zip';
  998. $zip_folder = new PclZip($temp_zip_file);
  999. foreach ($files as $key => $value) {
  1000. $zip_folder->add(api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/'.$value['title'], PCLZIP_OPT_REMOVE_PATH, api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp');
  1001. }
  1002. // Step 1: create the overview file and add it to the zip
  1003. $overview_file_content = generate_html_overview($files, array('filename'), array('title'));
  1004. $overview_file = $temp_zip_dir.'overview'.replace_dangerous_char(api_is_western_name_order() ? $_user['firstname'].' '.$_user['lastname'] : $_user['lastname'].' '.$_user['firstname'], 'strict').'.html';
  1005. $handle = fopen($overview_file, 'w');
  1006. fwrite($handle, $overview_file_content);
  1007. // todo: find a different solution for this because even 2 seconds is no guarantee.
  1008. sleep(2);
  1009. // Step 4: we add the overview file
  1010. $zip_folder->add($overview_file, PCLZIP_OPT_REMOVE_PATH, api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp');
  1011. // Step 5: send the file for download;
  1012. DocumentManager::file_send_for_download($temp_zip_file, true);
  1013. // Step 6: remove the files in the temp dir
  1014. foreach ($files as $key => $value) {
  1015. unlink(api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/'.$value['title']);
  1016. }
  1017. //unlink($overview_file);
  1018. exit;
  1019. }
  1020. /**
  1021. * @desc This function checks if the real filename of the dropbox files doesn't already exist in the temp folder. If this is the case then
  1022. * it will generate a different filename;
  1023. *
  1024. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1025. * @version march 2006
  1026. */
  1027. function check_file_name($file_name_2_check, $counter = 0) {
  1028. global $_course;
  1029. $new_file_name = $file_name_2_check;
  1030. if ($counter != 0) {
  1031. $new_file_name = $counter.$new_file_name;
  1032. }
  1033. if (!file_exists(api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/'.$new_file_name)) {
  1034. return $new_file_name;
  1035. } else {
  1036. $counter++;
  1037. $new_file_name = check_file_name($file_name_2_check, $counter);
  1038. return $new_file_name;
  1039. }
  1040. }
  1041. /**
  1042. * @desc Cleans the temp zip files that were created when users download several files or a whole folder at once.
  1043. * T
  1044. * @return true
  1045. * @todo
  1046. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1047. * @version march 2006
  1048. */
  1049. function cleanup_temp_dropbox() {
  1050. global $_course;
  1051. $handle = opendir(api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp');
  1052. while (false !== ($file = readdir($handle))) {
  1053. if ($file != '.' OR $file != '..') {
  1054. $name = str_replace('.zip', '', $file);
  1055. $name_part = explode('-', $name);
  1056. $timestamp_of_file = $name_part[count($name_part) - 1];
  1057. // if it is a dropboxdownloadfile and the file is older than one day then we delete it
  1058. if (strstr($file, 'dropboxdownload') AND $timestamp_of_file < (mktime() - 86400)) {
  1059. unlink(api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/'.$file);
  1060. }
  1061. }
  1062. }
  1063. closedir($handle);
  1064. return true;
  1065. }
  1066. /**
  1067. * @desc Generates the contents of a html file that gives an overview of all the files in the zip file.
  1068. * This is to know the information of the files that are inside the zip file (who send it, the comment, ...)
  1069. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, March 2006
  1070. * @author Ivan Tcholakov, 2010, code for html metadata has been added.
  1071. */
  1072. function generate_html_overview($files, $dont_show_columns = array(), $make_link = array()) {
  1073. $return = '<!DOCTYPE html'."\n";
  1074. $return .= "\t".'PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'."\n";
  1075. $return .= "\t".'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  1076. $return .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.api_get_language_isocode().'" lang="'.api_get_language_isocode().'">'."\n";
  1077. $return .= "<head>\n\t<title>".get_lang('OverviewOfFilesInThisZip')."</title>\n";
  1078. $return .= "\t".'<meta http-equiv="Content-Type" content="text/html; charset='.api_get_system_encoding().'" />'."\n";
  1079. $return .= "</head>\n\n";
  1080. $return .= '<body dir="'.api_get_text_direction().'">'."\n\n";
  1081. $return .= "<table border=\"1px\">\n";
  1082. $counter = 0;
  1083. foreach ($files as $key => $value) {
  1084. // Adding the header.
  1085. if ($counter == 0) {
  1086. $columns_array = array_keys($value);
  1087. $return .= "\n<tr>";
  1088. foreach ($columns_array as $columns_array_key => $columns_array_value) {
  1089. if (!in_array($columns_array_value, $dont_show_columns)) {
  1090. $return .= "\n\t<th>".$columns_array_value."</th>";
  1091. }
  1092. $column[] = $columns_array_value;
  1093. }
  1094. $return .= "\n</tr>\n";
  1095. }
  1096. $counter++;
  1097. // Adding the content.
  1098. $return .= "\n<tr>";
  1099. foreach ($column as $column_key => $column_value) {
  1100. if (!in_array($column_value,$dont_show_columns)) {
  1101. $return .= "\n\t<td>";
  1102. if (in_array($column_value, $make_link)) {
  1103. $return .= '<a href="'.$value[$column_value].'">'.$value[$column_value].'</a>';
  1104. } else {
  1105. $return .= $value[$column_value];
  1106. }
  1107. $return .= "</td>";
  1108. }
  1109. }
  1110. $return .= "\n</tr>\n";
  1111. }
  1112. $return .= "\n</table>\n\n</body>";
  1113. $return .= "\n</html>";
  1114. return $return;
  1115. }
  1116. /**
  1117. * @desc This function retrieves the number of feedback messages on every document. This function might become obsolete when
  1118. * the feedback becomes user individual.
  1119. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1120. * @version march 2006
  1121. */
  1122. function get_total_number_feedback($file_id = '') {
  1123. global $dropbox_cnf;
  1124. $sql = "SELECT COUNT(feedback_id) AS total, file_id FROM ".$dropbox_cnf['tbl_feedback']." GROUP BY file_id";
  1125. $result=Database::query($sql);
  1126. while ($row=Database::fetch_array($result)) {
  1127. $return[$row['file_id']] = $row['total'];
  1128. }
  1129. return $return;
  1130. }
  1131. /**
  1132. * @desc this function checks if the key exists. If this is the case it returns the value, if not it returns 0
  1133. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1134. * @version march 2006
  1135. */
  1136. function check_number_feedback($key, $array) {
  1137. if (is_array($array)) {
  1138. if (key_exists($key, $array)) {
  1139. return $array[$key];
  1140. } else {
  1141. return 0;
  1142. }
  1143. } else {
  1144. return 0;
  1145. }
  1146. }
  1147. /**
  1148. * Get the last access to a given tool of a given user
  1149. * @param $tool string the tool constant
  1150. * @param $course_code the course_id
  1151. * @param $user_id the id of the user
  1152. * @return string last tool access date
  1153. *
  1154. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1155. * @version march 2006
  1156. *
  1157. * @todo consider moving this function to a more appropriate place.
  1158. */
  1159. function get_last_tool_access($tool, $course_code='', $user_id='') {
  1160. global $_course, $_user;
  1161. // The default values of the parameters
  1162. if ($course_code == '') {
  1163. $course_code = $_course['id'];
  1164. }
  1165. if ($user_id == '') {
  1166. $user_id = $_user['user_id'];
  1167. }
  1168. // the table where the last tool access is stored (=track_e_lastaccess)
  1169. $table_last_access = Database::get_statistic_table('track_e_lastaccess');
  1170. $sql = "SELECT access_date FROM $table_last_access WHERE access_user_id='".Database::escape_string($user_id)."'
  1171. AND access_cours_code='".Database::escape_string($course_code)."'
  1172. AND access_tool='".Database::escape_string($tool)."'
  1173. ORDER BY access_date DESC
  1174. LIMIT 1";
  1175. $result = Database::query($sql);
  1176. $row = Database::fetch_array($result);
  1177. return $row['access_date'];
  1178. }