dropbox_functions.inc.php 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. use ChamiloSession as Session;
  4. /**
  5. * This file contains additional dropbox functions. Initially there were some
  6. * functions in the init files also but I have moved them over
  7. * to one file -- Patrick Cool <patrick.cool@UGent.be>, Ghent University.
  8. *
  9. * @author Julio Montoya adding c_id support
  10. */
  11. $this_section = SECTION_COURSES;
  12. $htmlHeadXtra[] = '<script>
  13. function setFocus(){
  14. $("#category_title").focus();
  15. }
  16. $(function() {
  17. setFocus();
  18. });
  19. </script>';
  20. /**
  21. * This function is a wrapper function for the multiple actions feature.
  22. *
  23. * @return string|null If there is a problem, return a string message, otherwise nothing
  24. *
  25. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  26. *
  27. * @version march 2006
  28. */
  29. function handle_multiple_actions()
  30. {
  31. $_user = api_get_user_info();
  32. $is_courseAdmin = api_is_course_admin();
  33. $is_courseTutor = api_is_course_tutor();
  34. // STEP 1: are we performing the actions on the received or on the sent files?
  35. if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'download_received') {
  36. $part = 'received';
  37. } elseif ($_POST['action'] == 'delete_sent' || $_POST['action'] == 'download_sent') {
  38. $part = 'sent';
  39. }
  40. // STEP 2: at least one file has to be selected. If not we return an error message
  41. $ids = isset($_GET['id']) ? $_GET['id'] : [];
  42. if (count($ids) > 0) {
  43. $checked_file_ids = $_POST['id'];
  44. } else {
  45. foreach ($_POST as $key => $value) {
  46. if (strstr($value, $part.'_') && $key != 'view_received_category' && $key != 'view_sent_category') {
  47. $checked_files = true;
  48. $checked_file_ids[] = intval(substr($value, strrpos($value, '_')));
  49. }
  50. }
  51. }
  52. $checked_file_ids = $_POST['id'];
  53. if (!is_array($checked_file_ids) || count($checked_file_ids) == 0) {
  54. return get_lang('Check at least one file.');
  55. }
  56. // Deleting
  57. if ($_POST['action'] == 'delete_received' || $_POST['action'] == 'delete_sent') {
  58. $dropboxfile = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
  59. foreach ($checked_file_ids as $key => $value) {
  60. if ($_GET['view'] == 'received') {
  61. $dropboxfile->deleteReceivedWork($value);
  62. $message = get_lang('The received file has been deleted.');
  63. }
  64. if ($_GET['view'] == 'sent' || empty($_GET['view'])) {
  65. $dropboxfile->deleteSentWork($value);
  66. $message = get_lang('The sent file has been deleted.');
  67. }
  68. }
  69. return $message;
  70. }
  71. // moving
  72. if (strstr($_POST['action'], 'move_')) {
  73. // check move_received_n or move_sent_n command
  74. if (strstr($_POST['action'], 'received')) {
  75. $part = 'received';
  76. $to_cat_id = str_replace('move_received_', '', $_POST['action']);
  77. } else {
  78. $part = 'sent';
  79. $to_cat_id = str_replace('move_sent_', '', $_POST['action']);
  80. }
  81. foreach ($checked_file_ids as $value) {
  82. store_move($value, $to_cat_id, $part);
  83. }
  84. return get_lang('The selected files have been moved.');
  85. }
  86. // STEP 3D: downloading
  87. if ($_POST['action'] == 'download_sent' || $_POST['action'] == 'download_received') {
  88. zip_download($checked_file_ids);
  89. }
  90. }
  91. /**
  92. * Get conf settings.
  93. *
  94. * @return array
  95. */
  96. function getDropboxConf()
  97. {
  98. return Session::read('dropbox_conf');
  99. }
  100. /**
  101. * This function deletes a dropbox category.
  102. *
  103. * @todo give the user the possibility what needs to be done with the files
  104. * in this category: move them to the root, download them as a zip, delete them
  105. *
  106. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  107. *
  108. * @version march 2006
  109. */
  110. function delete_category($action, $id, $user_id = null)
  111. {
  112. $course_id = api_get_course_int_id();
  113. $is_courseAdmin = api_is_course_admin();
  114. $is_courseTutor = api_is_course_tutor();
  115. if (empty($user_id)) {
  116. $user_id = api_get_user_id();
  117. }
  118. $cat = get_dropbox_category($id);
  119. if (count($cat) == 0) {
  120. return false;
  121. }
  122. if ($cat['user_id'] != $user_id && !api_is_platform_admin($user_id)) {
  123. return false;
  124. }
  125. // an additional check that might not be necessary
  126. if ($action == 'deletereceivedcategory') {
  127. $sentreceived = 'received';
  128. $entries_table = Database::get_course_table(TABLE_DROPBOX_POST);
  129. $id_field = 'file_id';
  130. $return_message = get_lang('The folder has been deleted');
  131. } elseif ($action == 'deletesentcategory') {
  132. $sentreceived = 'sent';
  133. $entries_table = Database::get_course_table(TABLE_DROPBOX_FILE);
  134. $id_field = 'id';
  135. $return_message = get_lang('The folder has been deleted');
  136. } else {
  137. return get_lang('Error');
  138. }
  139. // step 1: delete the category
  140. $sql = "DELETE FROM ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
  141. WHERE c_id = $course_id AND cat_id='".intval($id)."' AND $sentreceived='1'";
  142. Database::query($sql);
  143. // step 2: delete all the documents in this category
  144. $sql = "SELECT * FROM ".$entries_table."
  145. WHERE c_id = $course_id AND cat_id='".intval($id)."'";
  146. $result = Database::query($sql);
  147. while ($row = Database::fetch_array($result)) {
  148. $dropboxfile = new Dropbox_Person($user_id, $is_courseAdmin, $is_courseTutor);
  149. if ($action == 'deletereceivedcategory') {
  150. $dropboxfile->deleteReceivedWork($row[$id_field]);
  151. }
  152. if ($action == 'deletesentcategory') {
  153. $dropboxfile->deleteSentWork($row[$id_field]);
  154. }
  155. }
  156. return $return_message;
  157. }
  158. /**
  159. * Displays the form to move one individual file to a category.
  160. *
  161. *@ return html code of the form that appears in a message box.
  162. *
  163. * @author Julio Montoya - function rewritten
  164. */
  165. function display_move_form(
  166. $part,
  167. $id,
  168. $target = [],
  169. $extra_params = [],
  170. $viewReceivedCategory,
  171. $viewSentCategory,
  172. $view
  173. ) {
  174. $form = new FormValidator(
  175. 'form1',
  176. 'post',
  177. api_get_self().'?view_received_category='.$viewReceivedCategory.'&view_sent_category='.$viewSentCategory.'&view='.$view.'&'.$extra_params
  178. );
  179. $form->addElement('header', get_lang('Move file to'));
  180. $form->addElement('hidden', 'id', intval($id));
  181. $form->addElement('hidden', 'part', Security::remove_XSS($part));
  182. $options = ['0' => get_lang('root')];
  183. foreach ($target as $category) {
  184. $options[$category['cat_id']] = $category['cat_name'];
  185. }
  186. $form->addElement('select', 'move_target', get_lang('Move file to'), $options);
  187. $form->addButtonMove(get_lang('Move the file'), 'do_move');
  188. $form->display();
  189. }
  190. /**
  191. * This function moves a file to a different category.
  192. *
  193. * @param int $id the id of the file we are moving
  194. * @param int $target the id of the folder we are moving to
  195. * @param string $part are we moving a received file or a sent file?
  196. *
  197. * @return string string
  198. *
  199. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  200. *
  201. * @version march 2006
  202. */
  203. function store_move($id, $target, $part)
  204. {
  205. $_user = api_get_user_info();
  206. $course_id = api_get_course_int_id();
  207. if ((isset($id) && $id != '') &&
  208. (isset($target) && $target != '') &&
  209. (isset($part) && $part != '')
  210. ) {
  211. if ($part == 'received') {
  212. $sql = "UPDATE ".Database::get_course_table(TABLE_DROPBOX_POST)."
  213. SET cat_id = ".intval($target)."
  214. WHERE c_id = $course_id AND dest_user_id = ".intval($_user['user_id'])."
  215. AND file_id = ".intval($id)."";
  216. Database::query($sql);
  217. $return_message = get_lang('The received file has been moved.');
  218. }
  219. if ($part == 'sent') {
  220. $sql = "UPDATE ".Database::get_course_table(TABLE_DROPBOX_FILE)."
  221. SET cat_id = ".intval($target)."
  222. WHERE
  223. c_id = $course_id AND
  224. uploader_id = ".intval($_user['user_id'])." AND
  225. id = ".intval($id);
  226. Database::query($sql);
  227. $return_message = get_lang('The sent file has been moved');
  228. }
  229. } else {
  230. $return_message = get_lang('The file(s) can not be moved.');
  231. }
  232. return $return_message;
  233. }
  234. /**
  235. * This function retrieves all dropbox categories and returns them as an array.
  236. *
  237. * @param $filter default '', when we need only the categories of the sent or the received part
  238. *
  239. * @return array
  240. *
  241. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  242. *
  243. * @version march 2006
  244. */
  245. function get_dropbox_categories($filter = '')
  246. {
  247. $course_id = api_get_course_int_id();
  248. $_user = api_get_user_info();
  249. $return_array = [];
  250. $session_id = api_get_session_id();
  251. $condition_session = api_get_session_condition($session_id);
  252. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
  253. WHERE c_id = $course_id AND user_id='".$_user['user_id']."' $condition_session";
  254. $result = Database::query($sql);
  255. while ($row = Database::fetch_array($result)) {
  256. if (($filter == 'sent' && $row['sent'] == 1) ||
  257. ($filter == 'received' && $row['received'] == 1) || $filter == ''
  258. ) {
  259. $return_array[$row['cat_id']] = $row;
  260. }
  261. }
  262. return $return_array;
  263. }
  264. /**
  265. * Get a dropbox category details.
  266. *
  267. * @param int The category ID
  268. *
  269. * @return array The details of this category
  270. */
  271. function get_dropbox_category($id)
  272. {
  273. $course_id = api_get_course_int_id();
  274. $id = (int) $id;
  275. if (empty($id)) {
  276. return [];
  277. }
  278. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
  279. WHERE c_id = $course_id AND cat_id='".$id."'";
  280. $res = Database::query($sql);
  281. if ($res === false) {
  282. return [];
  283. }
  284. $row = Database::fetch_assoc($res);
  285. return $row;
  286. }
  287. /**
  288. * This functions stores a new dropboxcategory.
  289. *
  290. * @var it might not seem very elegant if you create a category in sent
  291. * and in received with the same name that you get two entries in the
  292. * dropbox_category table but it is the easiest solution. You get
  293. * cat_name | received | sent | user_id
  294. * test | 1 | 0 | 237
  295. * test | 0 | 1 | 237
  296. * more elegant would be
  297. * test | 1 | 1 | 237
  298. *
  299. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  300. *
  301. * @version march 2006
  302. */
  303. function store_addcategory()
  304. {
  305. $course_id = api_get_course_int_id();
  306. $_user = api_get_user_info();
  307. // check if the target is valid
  308. if ($_POST['target'] == 'sent') {
  309. $sent = 1;
  310. $received = 0;
  311. } elseif ($_POST['target'] == 'received') {
  312. $sent = 0;
  313. $received = 1;
  314. } else {
  315. return get_lang('Error');
  316. }
  317. // check if the category name is valid
  318. if ($_POST['category_name'] == '') {
  319. return ['type' => 'error', 'message' => get_lang('Please give a category name')];
  320. }
  321. if (!isset($_POST['edit_id'])) {
  322. $session_id = api_get_session_id();
  323. // step 3a, we check if the category doesn't already exist
  324. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
  325. WHERE
  326. c_id = $course_id AND
  327. user_id='".$_user['user_id']."' AND
  328. cat_name='".Database::escape_string($_POST['category_name'])."' AND
  329. received='".$received."' AND
  330. sent='$sent' AND
  331. session_id='$session_id'";
  332. $result = Database::query($sql);
  333. // step 3b, we add the category if it does not exist yet.
  334. if (Database::num_rows($result) == 0) {
  335. $params = [
  336. 'cat_id' => 0,
  337. 'c_id' => $course_id,
  338. 'cat_name' => $_POST['category_name'],
  339. 'received' => $received,
  340. 'sent' => $sent,
  341. 'user_id' => $_user['user_id'],
  342. 'session_id' => $session_id,
  343. ];
  344. $id = Database::insert(Database::get_course_table(TABLE_DROPBOX_CATEGORY), $params);
  345. if ($id) {
  346. $sql = "UPDATE ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)." SET cat_id = iid
  347. WHERE iid = $id";
  348. Database::query($sql);
  349. }
  350. return ['type' => 'confirmation', 'message' => get_lang('The folder has been created')];
  351. } else {
  352. return ['type' => 'error', 'message' => get_lang('This category already exists, please use a different name')];
  353. }
  354. } else {
  355. $params = [
  356. 'cat_name' => $_POST['category_name'],
  357. 'received' => $received,
  358. 'sent' => $sent,
  359. ];
  360. Database::update(
  361. Database::get_course_table(TABLE_DROPBOX_CATEGORY),
  362. $params,
  363. [
  364. 'c_id = ? AND user_id = ? AND cat_id = ?' => [
  365. $course_id,
  366. $_user['user_id'],
  367. $_POST['edit_id'],
  368. ],
  369. ]
  370. );
  371. return ['type' => 'confirmation', 'message' => get_lang('The category has been modified.')];
  372. }
  373. }
  374. /**
  375. * This function displays the form to add a new category.
  376. *
  377. * @param string $category_name this parameter is the name of the category (used when no section is selected)
  378. * @param int $id this is the id of the category we are editing
  379. *
  380. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  381. *
  382. * @version march 2006
  383. */
  384. function display_addcategory_form($category_name = '', $id = 0, $action = '')
  385. {
  386. $course_id = api_get_course_int_id();
  387. $title = get_lang('Add a new folder');
  388. $id = (int) $id;
  389. if (!empty($id)) {
  390. // retrieve the category we are editing
  391. $sql = "SELECT * FROM ".Database::get_course_table(TABLE_DROPBOX_CATEGORY)."
  392. WHERE c_id = $course_id AND cat_id = ".$id;
  393. $result = Database::query($sql);
  394. $row = Database::fetch_array($result);
  395. if (empty($category_name)) {
  396. // after an edit with an error we do not want to return to the
  397. // original name but the name we already modified.
  398. // (happens when createinrecievedfiles AND createinsentfiles are not checked)
  399. $category_name = $row['cat_name'];
  400. }
  401. if ($row['received'] == '1') {
  402. $target = 'received';
  403. }
  404. if ($row['sent'] == '1') {
  405. $target = 'sent';
  406. }
  407. $title = get_lang('Edit this category');
  408. }
  409. if ($action == 'addreceivedcategory') {
  410. $target = 'received';
  411. }
  412. if ($action == 'addsentcategory') {
  413. $target = 'sent';
  414. }
  415. if ($action == 'editcategory') {
  416. $text = get_lang('Edit category');
  417. } elseif ($action == 'addreceivedcategory' || $action == 'addsentcategory') {
  418. $text = get_lang('Create category');
  419. }
  420. $form = new FormValidator(
  421. 'add_new_category',
  422. 'post',
  423. api_get_self().'?'.api_get_cidreq().'&view='.Security::remove_XSS($_GET['view'])
  424. );
  425. $form->addElement('header', $title);
  426. if (!empty($id)) {
  427. $form->addElement('hidden', 'edit_id', $id);
  428. }
  429. $form->addElement('hidden', 'action', Security::remove_XSS($action));
  430. $form->addElement('hidden', 'target', Security::remove_XSS($target));
  431. $form->addElement('text', 'category_name', get_lang('Category name'));
  432. $form->addRule('category_name', get_lang('Required field'), 'required');
  433. $form->addButtonSave($text, 'StoreCategory');
  434. $defaults = [];
  435. $defaults['category_name'] = Security::remove_XSS($category_name);
  436. $form->setDefaults($defaults);
  437. $form->display();
  438. }
  439. /**
  440. * this function displays the form to upload a new item to the dropbox.
  441. *
  442. * @param $viewReceivedCategory
  443. * @param $viewSentCategory
  444. * @param $view
  445. * @param int $id
  446. *
  447. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  448. * @author Julio Montoya
  449. *
  450. * @version march 2006
  451. */
  452. function display_add_form($viewReceivedCategory, $viewSentCategory, $view, $id = 0)
  453. {
  454. $course_info = api_get_course_info();
  455. $_user = api_get_user_info();
  456. $is_courseAdmin = api_is_course_admin();
  457. $is_courseTutor = api_is_course_tutor();
  458. $origin = api_get_origin();
  459. $token = Security::get_token();
  460. $dropbox_person = new Dropbox_Person(
  461. api_get_user_id(),
  462. $is_courseAdmin,
  463. $is_courseTutor
  464. );
  465. $idCondition = !empty($id) ? '&id='.(int) $id : '';
  466. $url = api_get_self().'?view_received_category='.$viewReceivedCategory.'&view_sent_category='.$viewSentCategory.'&view='.$view.'&'.api_get_cidreq().$idCondition;
  467. $form = new FormValidator(
  468. 'sent_form',
  469. 'post',
  470. $url,
  471. null,
  472. [
  473. 'enctype' => 'multipart/form-data',
  474. 'onsubmit' => 'javascript: return checkForm(this);',
  475. ]
  476. );
  477. $form->addElement('header', get_lang('Share a new file'));
  478. $maxFileSize = api_get_setting('dropbox_max_filesize');
  479. $form->addElement('hidden', 'MAX_FILE_SIZE', $maxFileSize);
  480. $form->addElement('hidden', 'sec_token', $token);
  481. $form->addElement('hidden', 'origin', $origin);
  482. $form->addElement(
  483. 'file',
  484. 'file',
  485. get_lang('File upload'),
  486. ['onChange' => 'javascript: checkfile(this.value);']
  487. );
  488. $allowOverwrite = api_get_setting('dropbox_allow_overwrite');
  489. if ($allowOverwrite == 'true' && empty($idCondition)) {
  490. $form->addElement(
  491. 'checkbox',
  492. 'cb_overwrite',
  493. null,
  494. get_lang('Overwrite previous versions of same document?'),
  495. ['id' => 'cb_overwrite']
  496. );
  497. }
  498. // List of all users in this course and all virtual courses combined with it
  499. if (api_get_session_id()) {
  500. $complete_user_list_for_dropbox = [];
  501. if (api_get_setting('dropbox_allow_student_to_student') == 'true' || $_user['status'] != STUDENT) {
  502. $complete_user_list_for_dropbox = CourseManager:: get_user_list_from_course_code(
  503. $course_info['code'],
  504. api_get_session_id(),
  505. null,
  506. null,
  507. 0,
  508. false,
  509. false,
  510. false,
  511. [],
  512. [],
  513. [],
  514. true
  515. );
  516. }
  517. $complete_user_list2 = CourseManager::get_coach_list_from_course_code(
  518. $course_info['code'],
  519. api_get_session_id()
  520. );
  521. $generalCoachList = [];
  522. $courseCoachList = [];
  523. foreach ($complete_user_list2 as $coach) {
  524. if ($coach['type'] == 'general_coach') {
  525. $generalCoachList[] = $coach;
  526. } else {
  527. $courseCoachList[] = $coach;
  528. }
  529. }
  530. $hideCourseCoach = api_get_setting('dropbox_hide_course_coach');
  531. if ($hideCourseCoach == 'false') {
  532. $complete_user_list_for_dropbox = array_merge(
  533. $complete_user_list_for_dropbox,
  534. $courseCoachList
  535. );
  536. }
  537. $hideGeneralCoach = api_get_setting('dropbox_hide_general_coach');
  538. if ($hideGeneralCoach == 'false') {
  539. $complete_user_list_for_dropbox = array_merge(
  540. $complete_user_list_for_dropbox,
  541. $generalCoachList
  542. );
  543. }
  544. } else {
  545. if (api_get_setting('dropbox_allow_student_to_student') == 'true' || $_user['status'] != STUDENT) {
  546. $complete_user_list_for_dropbox = CourseManager::get_user_list_from_course_code(
  547. $course_info['code'],
  548. api_get_session_id(),
  549. null,
  550. null,
  551. null,
  552. false,
  553. false,
  554. false,
  555. [],
  556. [],
  557. [],
  558. true
  559. );
  560. } else {
  561. $complete_user_list_for_dropbox = CourseManager::get_teacher_list_from_course_code(
  562. $course_info['code'],
  563. false
  564. );
  565. }
  566. }
  567. if (!empty($complete_user_list_for_dropbox)) {
  568. foreach ($complete_user_list_for_dropbox as $k => $e) {
  569. $complete_user_list_for_dropbox[$k] = $e + [
  570. 'lastcommafirst' => api_get_person_name(
  571. $e['firstname'],
  572. $e['lastname']
  573. ),
  574. ];
  575. }
  576. $complete_user_list_for_dropbox = TableSort::sort_table($complete_user_list_for_dropbox, 'lastcommafirst');
  577. }
  578. /*
  579. Create the options inside the select box:
  580. List all selected users their user id as value and a name string as display
  581. */
  582. $current_user_id = '';
  583. $allowStudentToStudent = api_get_setting('dropbox_allow_student_to_student');
  584. $options = [];
  585. $userGroup = new UserGroup();
  586. foreach ($complete_user_list_for_dropbox as $current_user) {
  587. if ((
  588. $dropbox_person->isCourseTutor
  589. || $dropbox_person->isCourseAdmin
  590. || $allowStudentToStudent == 'true'
  591. || $current_user['status'] != 5 // Always allow teachers.
  592. || $current_user['is_tutor'] == 1 // Always allow tutors.
  593. ) && $current_user['user_id'] != $_user['user_id']) { // Don't include yourself.
  594. if ($current_user['user_id'] == $current_user_id) {
  595. continue;
  596. }
  597. $userId = $current_user['user_id'];
  598. $userInfo = api_get_user_info($userId);
  599. if ($userInfo['status'] != INVITEE) {
  600. $groupNameListToString = '';
  601. if (!empty($groups)) {
  602. $groupNameList = array_column($groups, 'name');
  603. $groupNameListToString = ' - ['.implode(', ', $groupNameList).']';
  604. }
  605. $groups = $userGroup->getUserGroupListByUser($userId);
  606. $full_name = $userInfo['complete_name'].$groupNameListToString;
  607. $current_user_id = $current_user['user_id'];
  608. $options['user_'.$current_user_id] = $full_name;
  609. }
  610. }
  611. }
  612. /*
  613. * Show groups
  614. */
  615. $allowGroups = api_get_setting('dropbox_allow_group');
  616. if (($dropbox_person->isCourseTutor || $dropbox_person->isCourseAdmin)
  617. && $allowGroups == 'true' || $allowStudentToStudent == 'true'
  618. ) {
  619. $complete_group_list_for_dropbox = GroupManager::get_group_list(null, $course_info);
  620. if (count($complete_group_list_for_dropbox) > 0) {
  621. foreach ($complete_group_list_for_dropbox as $current_group) {
  622. if ($current_group['number_of_members'] > 0) {
  623. $options['group_'.$current_group['id']] = 'G: '.$current_group['name'].' - '.$current_group['number_of_members'].' '.get_lang('Users');
  624. }
  625. }
  626. }
  627. }
  628. $allowUpload = api_get_setting('dropbox_allow_just_upload');
  629. if ($allowUpload == 'true') {
  630. $options['user_'.$_user['user_id']] = get_lang('---Just upload---');
  631. }
  632. if (empty($idCondition)) {
  633. $form->addSelect(
  634. 'recipients',
  635. get_lang('Send to'),
  636. $options,
  637. [
  638. 'multiple' => 'multiple',
  639. 'size' => '10',
  640. ]
  641. );
  642. }
  643. $form->addButtonUpload(get_lang('Upload'), 'submitWork');
  644. $headers = [
  645. get_lang('Upload'),
  646. get_lang('Upload').' ('.get_lang('Simple').')',
  647. ];
  648. $multipleForm = new FormValidator(
  649. 'sent_multiple',
  650. 'post',
  651. '#',
  652. null,
  653. ['enctype' => 'multipart/form-data', 'id' => 'fileupload']
  654. );
  655. if (empty($idCondition)) {
  656. $multipleForm->addSelect(
  657. 'recipients',
  658. get_lang('Send to'),
  659. $options,
  660. [
  661. 'multiple' => 'multiple',
  662. 'size' => '10',
  663. 'id' => 'recipient_form',
  664. ]
  665. );
  666. }
  667. $url = api_get_path(WEB_AJAX_PATH).'dropbox.ajax.php?'.api_get_cidreq().'&a=upload_file&'.$idCondition;
  668. if (empty($idCondition)) {
  669. $multipleForm->addHtml('<div id="multiple_form" style="display:none">');
  670. }
  671. $multipleForm->addMultipleUpload($url);
  672. if (empty($idCondition)) {
  673. $multipleForm->addHtml('</div>');
  674. }
  675. echo Display::tabs(
  676. $headers,
  677. [$multipleForm->returnForm(), $form->returnForm()],
  678. 'tabs'
  679. );
  680. }
  681. /**
  682. * Checks if there are files in the dropbox_file table that aren't used anymore in dropbox_person table.
  683. * If there are, all entries concerning the file are deleted from the db + the file is deleted from the server.
  684. */
  685. function removeUnusedFiles()
  686. {
  687. $_course = api_get_course_info();
  688. $course_id = $_course['real_id'];
  689. // select all files that aren't referenced anymore
  690. $sql = "SELECT DISTINCT f.id, f.filename
  691. FROM ".Database::get_course_table(TABLE_DROPBOX_FILE)." f
  692. LEFT JOIN ".Database::get_course_table(TABLE_DROPBOX_PERSON)." p
  693. ON (f.id = p.file_id)
  694. WHERE p.user_id IS NULL AND
  695. f.c_id = $course_id
  696. ";
  697. $result = Database::query($sql);
  698. while ($res = Database::fetch_array($result)) {
  699. //delete the selected files from the post and file tables
  700. $sql = "DELETE FROM ".Database::get_course_table(TABLE_DROPBOX_POST)."
  701. WHERE c_id = $course_id AND file_id = '".$res['id']."'";
  702. Database::query($sql);
  703. $sql = "DELETE FROM ".Database::get_course_table(TABLE_DROPBOX_FILE)."
  704. WHERE c_id = $course_id AND id ='".$res['id']."'";
  705. Database::query($sql);
  706. //delete file from server
  707. @unlink(api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$res['filename']);
  708. }
  709. }
  710. /**
  711. * Mailing zip-file is posted to (dest_user_id = ) mailing pseudo_id
  712. * and is only visible to its uploader (user_id).
  713. *
  714. * Mailing content files have uploader_id == mailing pseudo_id, a normal recipient,
  715. * and are visible initially to recipient and pseudo_id.
  716. *
  717. * @author René Haentjens, Ghent University
  718. *
  719. * @todo check if this function is still necessary.
  720. */
  721. function getUserOwningThisMailing($mailingPseudoId, $owner = 0, $or_die = '')
  722. {
  723. $course_id = api_get_course_int_id();
  724. $mailingPseudoId = (int) $mailingPseudoId;
  725. $sql = "SELECT f.uploader_id
  726. FROM ".Database::get_course_table(TABLE_DROPBOX_FILE)." f
  727. LEFT JOIN ".Database::get_course_table(TABLE_DROPBOX_POST)." p
  728. ON (f.id = p.file_id AND f.c_id = $course_id AND p.c_id = $course_id)
  729. WHERE
  730. p.dest_user_id = '".$mailingPseudoId."' AND
  731. p.c_id = $course_id
  732. ";
  733. $result = Database::query($sql);
  734. if (!($res = Database::fetch_array($result))) {
  735. die(get_lang('An error has occured. Please contact your system administrator.').' (code 901)');
  736. }
  737. if ($owner == 0) {
  738. return $res['uploader_id'];
  739. }
  740. if ($res['uploader_id'] == $owner) {
  741. return true;
  742. }
  743. die(get_lang('An error has occured. Please contact your system administrator.').' (code '.$or_die.')');
  744. }
  745. /**
  746. * @author René Haentjens, Ghent University
  747. *
  748. * @todo check if this function is still necessary.
  749. */
  750. function removeMoreIfMailing($file_id)
  751. {
  752. $course_id = api_get_course_int_id();
  753. // when deleting a mailing zip-file (posted to mailingPseudoId):
  754. // 1. the detail window is no longer reachable, so
  755. // for all content files, delete mailingPseudoId from person-table
  756. // 2. finding the owner (getUserOwningThisMailing) is no longer possible, so
  757. // for all content files, replace mailingPseudoId by owner as uploader
  758. $file_id = (int) $file_id;
  759. $sql = "SELECT p.dest_user_id
  760. FROM ".Database::get_course_table(TABLE_DROPBOX_POST)." p
  761. WHERE c_id = $course_id AND p.file_id = '".$file_id."'";
  762. $result = Database::query($sql);
  763. if ($res = Database::fetch_array($result)) {
  764. $mailingPseudoId = $res['dest_user_id'];
  765. $mailId = get_mail_id_base();
  766. if ($mailingPseudoId > $mailId) {
  767. $sql = "DELETE FROM ".Database::get_course_table(TABLE_DROPBOX_PERSON)."
  768. WHERE c_id = $course_id AND user_id='".$mailingPseudoId."'";
  769. Database::query($sql);
  770. $sql = "UPDATE ".Database::get_course_table(TABLE_DROPBOX_FILE)."
  771. SET uploader_id='".api_get_user_id()."'
  772. WHERE c_id = $course_id AND uploader_id='".$mailingPseudoId."'";
  773. Database::query($sql);
  774. }
  775. }
  776. }
  777. /**
  778. * @param array $file
  779. * @param Dropbox_SentWork $work
  780. *
  781. * @return array|string|null
  782. */
  783. function store_add_dropbox($file = [], $work = null)
  784. {
  785. $_course = api_get_course_info();
  786. $_user = api_get_user_info();
  787. if (empty($file)) {
  788. $file = isset($_FILES['file']) ? $_FILES['file'] : null;
  789. }
  790. if (empty($work)) {
  791. // Validating the form data
  792. // there are no recipients selected
  793. if (!isset($_POST['recipients']) || count($_POST['recipients']) <= 0) {
  794. return get_lang('You must select at least one destinee');
  795. } else {
  796. // Check if all the recipients are valid
  797. $thisIsAMailing = false;
  798. $thisIsJustUpload = false;
  799. foreach ($_POST['recipients'] as $rec) {
  800. if ($rec == 'mailing') {
  801. $thisIsAMailing = true;
  802. } elseif ($rec == 'upload') {
  803. $thisIsJustUpload = true;
  804. } elseif (strpos($rec, 'user_') === 0 &&
  805. !CourseManager::is_user_subscribed_in_course(
  806. substr($rec, strlen('user_')),
  807. $_course['code'],
  808. true
  809. )
  810. ) {
  811. Display::addFlash(
  812. Display::return_message(
  813. get_lang('Invalid user detected.'),
  814. 'warning'
  815. )
  816. );
  817. return false;
  818. } elseif (strpos($rec, 'group_') !== 0 && strpos($rec, 'user_') !== 0) {
  819. Display::addFlash(
  820. Display::return_message(
  821. get_lang('Invalid group detected.'),
  822. 'warning'
  823. )
  824. );
  825. return false;
  826. }
  827. }
  828. }
  829. // we are doing a mailing but an additional recipient is selected
  830. if ($thisIsAMailing && (count($_POST['recipients']) != 1)) {
  831. Display::addFlash(
  832. Display::return_message(
  833. get_lang('Mailing cannot be combined with other recipients'),
  834. 'warning'
  835. )
  836. );
  837. return false;
  838. }
  839. // we are doing a just upload but an additional recipient is selected.
  840. // note: why can't this be valid? It is like sending a document to
  841. // yourself AND to a different person (I do this quite often with my e-mails)
  842. if ($thisIsJustUpload && (count($_POST['recipients']) != 1)) {
  843. Display::addFlash(
  844. Display::return_message(
  845. get_lang('Just Upload cannot be combined with other recipients'),
  846. 'warning'
  847. )
  848. );
  849. return false;
  850. }
  851. }
  852. if (empty($file['name'])) {
  853. Display::addFlash(Display::return_message(get_lang('You didn\'t specify a file to upload.'), 'warning'));
  854. return false;
  855. }
  856. // are we overwriting a previous file or sending a new one
  857. $dropbox_overwrite = false;
  858. if (isset($_POST['cb_overwrite']) && $_POST['cb_overwrite']) {
  859. $dropbox_overwrite = true;
  860. }
  861. // doing the upload
  862. $dropbox_filename = $file['name'];
  863. $dropbox_filesize = $file['size'];
  864. $dropbox_filetype = $file['type'];
  865. $dropbox_filetmpname = $file['tmp_name'];
  866. // check if the filesize does not exceed the allowed size.
  867. $maxFileSize = api_get_setting('dropbox_max_filesize');
  868. if ($dropbox_filesize <= 0 || $dropbox_filesize > $maxFileSize) {
  869. Display::addFlash(Display::return_message(get_lang('This file\'s volume is too big.'), 'warning'));
  870. return false;
  871. }
  872. // check if the file is actually uploaded
  873. if (!is_uploaded_file($dropbox_filetmpname)) { // check user fraud : no clean error msg.
  874. Display::addFlash(Display::return_message(get_lang('The file is not uploaded.'), 'warning'));
  875. return false;
  876. }
  877. $upload_ok = process_uploaded_file($file, true);
  878. if (!$upload_ok) {
  879. return null;
  880. }
  881. // Try to add an extension to the file if it hasn't got one
  882. $dropbox_filename = add_ext_on_mime($dropbox_filename, $dropbox_filetype);
  883. // Replace dangerous characters
  884. $dropbox_filename = api_replace_dangerous_char($dropbox_filename);
  885. // Transform any .php file in .phps fo security
  886. $dropbox_filename = php2phps($dropbox_filename);
  887. //filter extension
  888. if (!filter_extension($dropbox_filename)) {
  889. Display::addFlash(
  890. Display::return_message(
  891. get_lang('File upload failed: this file extension or file type is prohibited'),
  892. 'warning'
  893. )
  894. );
  895. return false;
  896. }
  897. // set title
  898. $dropbox_title = $dropbox_filename;
  899. // note: I think we could better migrate everything from here on to
  900. // separate functions: store_new_dropbox, store_new_mailing, store_just_upload
  901. if ($dropbox_overwrite && empty($work)) {
  902. $dropbox_person = new Dropbox_Person(
  903. $_user['user_id'],
  904. api_is_course_admin(),
  905. api_is_course_tutor()
  906. );
  907. $mailId = get_mail_id_base();
  908. foreach ($dropbox_person->sentWork as $w) {
  909. if ($w->title == $dropbox_filename) {
  910. if (($w->recipients[0]['id'] > $mailId) xor $thisIsAMailing) {
  911. Display::addFlash(Display::return_message(get_lang('Mailing cannot be overwritten by non-mailing and vice-versa'), 'warning'));
  912. return false;
  913. }
  914. if (($w->recipients[0]['id'] == $_user['user_id']) xor $thisIsJustUpload) {
  915. Display::addFlash(Display::return_message(get_lang('Just Upload cannot be combined with other recipients'), 'warning'));
  916. return false;
  917. }
  918. $dropbox_filename = $w->filename;
  919. $found = true; // note: do we still need this?
  920. break;
  921. }
  922. }
  923. } else { // rename file to login_filename_uniqueId format
  924. $dropbox_filename = $_user['username']."_".$dropbox_filename."_".uniqid('');
  925. }
  926. if (empty($work)) {
  927. // creating the array that contains all the users who will receive the file
  928. $new_work_recipients = [];
  929. foreach ($_POST['recipients'] as $rec) {
  930. if (strpos($rec, 'user_') === 0) {
  931. $new_work_recipients[] = substr($rec, strlen('user_'));
  932. } elseif (strpos($rec, 'group_') === 0) {
  933. $groupInfo = GroupManager::get_group_properties(substr($rec, strlen('group_')));
  934. $userList = GroupManager::get_subscribed_users($groupInfo);
  935. foreach ($userList as $usr) {
  936. if (!in_array($usr['user_id'], $new_work_recipients) && $usr['user_id'] != $_user['user_id']) {
  937. $new_work_recipients[] = $usr['user_id'];
  938. }
  939. }
  940. }
  941. }
  942. }
  943. @move_uploaded_file(
  944. $dropbox_filetmpname,
  945. api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$dropbox_filename
  946. );
  947. $b_send_mail = api_get_course_setting('email_alert_on_new_doc_dropbox');
  948. if ($b_send_mail && empty($work)) {
  949. foreach ($new_work_recipients as $recipient_id) {
  950. $recipent_temp = api_get_user_info($recipient_id);
  951. $additionalParameters = [
  952. 'smsType' => SmsPlugin::NEW_FILE_SHARED_COURSE_BY,
  953. 'userId' => $recipient_id,
  954. 'courseTitle' => $_course['title'],
  955. 'userUsername' => $recipent_temp['username'],
  956. ];
  957. api_mail_html(
  958. api_get_person_name(
  959. $recipent_temp['firstname'].' '.$recipent_temp['lastname'],
  960. null,
  961. PERSON_NAME_EMAIL_ADDRESS
  962. ),
  963. $recipent_temp['email'],
  964. get_lang('A new file has been sent in the dropbox'),
  965. get_lang('A new file has been sent in the dropboxContent').' <a href="'.api_get_path(WEB_CODE_PATH).'dropbox/index.php?'.api_get_cidreq().'">'.get_lang('See file').'</a>'.
  966. "\n\n".
  967. api_get_person_name(
  968. $_user['firstName'],
  969. $_user['lastName'],
  970. null,
  971. PERSON_NAME_EMAIL_ADDRESS
  972. )."\n".get_lang('e-mail')." : ".$_user['mail'],
  973. api_get_person_name(
  974. $_user['firstName'],
  975. $_user['lastName'],
  976. null,
  977. PERSON_NAME_EMAIL_ADDRESS
  978. ),
  979. $_user['mail'],
  980. null,
  981. null,
  982. null,
  983. $additionalParameters
  984. );
  985. }
  986. }
  987. if (empty($work)) {
  988. // Create new
  989. $result = new Dropbox_SentWork(
  990. $_user['user_id'],
  991. $dropbox_title,
  992. isset($_POST['description']) ? $_POST['description'] : '',
  993. api_get_user_id(),
  994. $dropbox_filename,
  995. $dropbox_filesize,
  996. $new_work_recipients
  997. );
  998. } else {
  999. // Update
  1000. $work->title = $dropbox_title;
  1001. $work->filename = $dropbox_filename;
  1002. $work->filesize = $dropbox_filesize;
  1003. $work->upload_date = api_get_utc_datetime();
  1004. $work->last_upload_date = api_get_utc_datetime();
  1005. $work->description = isset($_POST['description']) ? $_POST['description'] : '';
  1006. $work->uploader_id = api_get_user_id();
  1007. $work->updateFile();
  1008. $result = $work;
  1009. }
  1010. Security::clear_token();
  1011. Display::addFlash(Display::return_message(get_lang('The file has successfully been uploaded.')));
  1012. return $result;
  1013. }
  1014. /**
  1015. * Transforms the array containing all the feedback into something visually attractive.
  1016. *
  1017. * @param an array containing all the feedback about the given message
  1018. *
  1019. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1020. *
  1021. * @version march 2006
  1022. */
  1023. function feedback($array, $url)
  1024. {
  1025. $output = null;
  1026. foreach ($array as $value) {
  1027. $output .= format_feedback($value);
  1028. }
  1029. $output .= feedback_form($url);
  1030. return $output;
  1031. }
  1032. /**
  1033. * This function returns the html code to display the feedback messages on a given dropbox file.
  1034. *
  1035. * @param $feedback_array an array that contains all the feedback messages about the given document
  1036. *
  1037. * @return string code
  1038. *
  1039. * @todo add the form for adding new comment (if the other party has not deleted it yet).
  1040. *
  1041. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1042. *
  1043. * @version march 2006
  1044. */
  1045. function format_feedback($feedback)
  1046. {
  1047. $userInfo = api_get_user_info($feedback['author_user_id']);
  1048. $output = UserManager::getUserProfileLink($userInfo);
  1049. $output .= '&nbsp;&nbsp;'.Display::dateToStringAgoAndLongDate($feedback['feedback_date']).'<br />';
  1050. $output .= '<div style="padding-top:6px">'.nl2br($feedback['feedback']).'</div><hr size="1" noshade/><br />';
  1051. return $output;
  1052. }
  1053. /**
  1054. * this function returns the code for the form for adding a new feedback message to a dropbox file.
  1055. *
  1056. * @param $url url string
  1057. *
  1058. * @return string code
  1059. *
  1060. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1061. *
  1062. * @version march 2006
  1063. */
  1064. function feedback_form($url)
  1065. {
  1066. $return = '<div class="feeback-form">';
  1067. $number_users_who_see_file = check_if_file_exist($_GET['id']);
  1068. if ($number_users_who_see_file) {
  1069. $token = Security::get_token();
  1070. $return .= '<div class="form-group">';
  1071. $return .= '<input type="hidden" name="sec_token" value="'.$token.'"/>';
  1072. $return .= '<label class="col-sm-3 control-label">'.get_lang('Add feedback');
  1073. $return .= '</label>';
  1074. $return .= '<div class="col-sm-6">';
  1075. $return .= '<textarea name="feedback" class="form-control" rows="4"></textarea>';
  1076. $return .= '</div>';
  1077. $return .= '<div class="col-sm-3">';
  1078. $return .= '<div class="pull-right"><a class="btn btn-default btn-sm" href="'.$url.'"><i class="fa fa-times" aria-hidden="true"></i></a></div>';
  1079. $return .= '<button type="submit" class="btn btn-primary btn-sm" name="store_feedback" value="'.get_lang('Validate').'"
  1080. onclick="javascript: document.form_dropbox.attributes.action.value = document.location;">'.get_lang('Add/Edit a comment to').'</button>';
  1081. $return .= '</div>';
  1082. $return .= '</div>';
  1083. $return .= '</div>';
  1084. } else {
  1085. $return .= get_lang('All users have deleted the file so nobody will see the feedback you are adding.');
  1086. }
  1087. return $return;
  1088. }
  1089. function user_can_download_file($id, $user_id)
  1090. {
  1091. $course_id = api_get_course_int_id();
  1092. $id = (int) $id;
  1093. $user_id = (int) $user_id;
  1094. $sql = "SELECT file_id
  1095. FROM ".Database::get_course_table(TABLE_DROPBOX_PERSON)."
  1096. WHERE c_id = $course_id AND user_id = $user_id AND file_id = ".$id;
  1097. $result = Database::query($sql);
  1098. $number_users_who_see_file = Database::num_rows($result);
  1099. $sql = "SELECT file_id
  1100. FROM ".Database::get_course_table(TABLE_DROPBOX_POST)."
  1101. WHERE c_id = $course_id AND dest_user_id = $user_id AND file_id = ".$id;
  1102. $result = Database::query($sql);
  1103. $count = Database::num_rows($result);
  1104. return $number_users_who_see_file > 0 || $count > 0;
  1105. }
  1106. // we now check if the other users have not delete this document yet.
  1107. // If this is the case then it is useless to see the
  1108. // add feedback since the other users will never get to see the feedback.
  1109. function check_if_file_exist($id)
  1110. {
  1111. $id = (int) $id;
  1112. $course_id = api_get_course_int_id();
  1113. $sql = "SELECT file_id
  1114. FROM ".Database::get_course_table(TABLE_DROPBOX_PERSON)."
  1115. WHERE c_id = $course_id AND file_id = ".$id;
  1116. $result = Database::query($sql);
  1117. $number_users_who_see_file = Database::num_rows($result);
  1118. $sql = "SELECT file_id
  1119. FROM ".Database::get_course_table(TABLE_DROPBOX_POST)."
  1120. WHERE c_id = $course_id AND file_id = ".$id;
  1121. $result = Database::query($sql);
  1122. $count = Database::num_rows($result);
  1123. return $number_users_who_see_file > 0 || $count > 0;
  1124. }
  1125. /**
  1126. * @return string language string (depending on the success or failure
  1127. *
  1128. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1129. *
  1130. * @version march 2006
  1131. */
  1132. function store_feedback()
  1133. {
  1134. if (!is_numeric($_GET['id'])) {
  1135. return get_lang('Feedback error');
  1136. }
  1137. $course_id = api_get_course_int_id();
  1138. if (empty($_POST['feedback'])) {
  1139. return get_lang('Please type some text.');
  1140. } else {
  1141. $table = Database::get_course_table(TABLE_DROPBOX_FEEDBACK);
  1142. $params = [
  1143. 'c_id' => $course_id,
  1144. 'file_id' => $_GET['id'],
  1145. 'author_user_id' => api_get_user_id(),
  1146. 'feedback' => $_POST['feedback'],
  1147. 'feedback_date' => api_get_utc_datetime(),
  1148. 'feedback_id' => 0,
  1149. ];
  1150. $id = Database::insert($table, $params);
  1151. if ($id) {
  1152. $sql = "UPDATE $table SET feedback_id = iid WHERE iid = $id";
  1153. Database::query($sql);
  1154. }
  1155. return get_lang('The feedback message has been stored');
  1156. }
  1157. }
  1158. /**
  1159. * This function downloads all the files of the input array into one zip.
  1160. *
  1161. * @param array $fileList containing all the ids of the files that have to be downloaded
  1162. *
  1163. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1164. *
  1165. * @todo consider removing the check if the user has received or sent this file (zip download of a folder already sufficiently checks for this).
  1166. * @todo integrate some cleanup function that removes zip files that are older than 2 days
  1167. *
  1168. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1169. * @author Julio Montoya Addin c_id support
  1170. *
  1171. * @version march 2006
  1172. */
  1173. function zip_download($fileList)
  1174. {
  1175. $_course = api_get_course_info();
  1176. $course_id = api_get_course_int_id();
  1177. $fileList = array_map('intval', $fileList);
  1178. // note: we also have to add the check if the user has received or sent this file.
  1179. $sql = "SELECT DISTINCT file.filename, file.title, file.author, file.description
  1180. FROM ".Database::get_course_table(TABLE_DROPBOX_FILE)." file
  1181. INNER JOIN ".Database::get_course_table(TABLE_DROPBOX_PERSON)." person
  1182. ON (person.file_id=file.id AND file.c_id = $course_id AND person.c_id = $course_id)
  1183. INNER JOIN ".Database::get_course_table(TABLE_DROPBOX_POST)." post
  1184. ON (post.file_id = file.id AND post.c_id = $course_id AND file.c_id = $course_id)
  1185. WHERE
  1186. file.id IN (".implode(', ', $fileList).") AND
  1187. file.id = person.file_id AND
  1188. (
  1189. person.user_id = '".api_get_user_id()."' OR
  1190. post.dest_user_id = '".api_get_user_id()."'
  1191. ) ";
  1192. $result = Database::query($sql);
  1193. $files = [];
  1194. while ($row = Database::fetch_array($result)) {
  1195. $files[$row['filename']] = [
  1196. 'filename' => $row['filename'],
  1197. 'title' => $row['title'],
  1198. 'author' => $row['author'],
  1199. 'description' => $row['description'],
  1200. ];
  1201. }
  1202. // Step 3: create the zip file and add all the files to it
  1203. $temp_zip_file = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
  1204. Session::write('dropbox_files_to_download', $files);
  1205. $zip = new PclZip($temp_zip_file);
  1206. foreach ($files as $value) {
  1207. $zip->add(
  1208. api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'],
  1209. PCLZIP_OPT_REMOVE_ALL_PATH,
  1210. PCLZIP_CB_PRE_ADD,
  1211. 'my_pre_add_callback'
  1212. );
  1213. }
  1214. Session::erase('dropbox_files_to_download');
  1215. $name = 'dropbox-'.api_get_utc_datetime().'.zip';
  1216. $result = DocumentManager::file_send_for_download($temp_zip_file, true, $name);
  1217. if ($result === false) {
  1218. api_not_allowed(true);
  1219. }
  1220. @unlink($temp_zip_file);
  1221. exit;
  1222. }
  1223. /**
  1224. * This is a callback function to decrypt the files in the zip file
  1225. * to their normal filename (as stored in the database).
  1226. *
  1227. * @param array $p_event a variable of PCLZip
  1228. * @param array $p_header a variable of PCLZip
  1229. *
  1230. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1231. *
  1232. * @version march 2006
  1233. */
  1234. function my_pre_add_callback($p_event, &$p_header)
  1235. {
  1236. $files = Session::read('dropbox_files_to_download');
  1237. $p_header['stored_filename'] = $files[$p_header['stored_filename']]['title'];
  1238. return 1;
  1239. }
  1240. /**
  1241. * @desc Generates the contents of a html file that gives an overview of all the files in the zip file.
  1242. * This is to know the information of the files that are inside the zip file (who send it, the comment, ...)
  1243. *
  1244. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, March 2006
  1245. * @author Ivan Tcholakov, 2010, code for html metadata has been added.
  1246. */
  1247. function generate_html_overview($files, $dont_show_columns = [], $make_link = [])
  1248. {
  1249. $return = '<!DOCTYPE html'."\n";
  1250. $return .= "\t".'PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'."\n";
  1251. $return .= "\t".'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
  1252. $return .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.api_get_language_isocode().'" lang="'.api_get_language_isocode().'">'."\n";
  1253. $return .= "<head>\n\t<title>".get_lang('Overview of diles in this Zip')."</title>\n";
  1254. $return .= "\t".'<meta http-equiv="Content-Type" content="text/html; charset='.api_get_system_encoding().'" />'."\n";
  1255. $return .= "</head>\n\n";
  1256. $return .= '<body dir="'.api_get_text_direction().'">'."\n\n";
  1257. $return .= "<table border=\"1px\">\n";
  1258. $counter = 0;
  1259. foreach ($files as $value) {
  1260. // Adding the header.
  1261. if ($counter == 0) {
  1262. $columns_array = array_keys($value);
  1263. $return .= "\n<tr>";
  1264. foreach ($columns_array as $columns_array_key => $columns_array_value) {
  1265. if (!in_array($columns_array_value, $dont_show_columns)) {
  1266. $return .= "\n\t<th>".$columns_array_value."</th>";
  1267. }
  1268. $column[] = $columns_array_value;
  1269. }
  1270. $return .= "\n</tr>\n";
  1271. }
  1272. $counter++;
  1273. // Adding the content.
  1274. $return .= "\n<tr>";
  1275. foreach ($column as $column_key => $column_value) {
  1276. if (!in_array($column_value, $dont_show_columns)) {
  1277. $return .= "\n\t<td>";
  1278. if (in_array($column_value, $make_link)) {
  1279. $return .= '<a href="'.$value[$column_value].'">'.$value[$column_value].'</a>';
  1280. } else {
  1281. $return .= $value[$column_value];
  1282. }
  1283. $return .= "</td>";
  1284. }
  1285. }
  1286. $return .= "\n</tr>\n";
  1287. }
  1288. $return .= "\n</table>\n\n</body>";
  1289. $return .= "\n</html>";
  1290. return $return;
  1291. }
  1292. /**
  1293. * @desc This function retrieves the number of feedback messages on every
  1294. * document. This function might become obsolete when
  1295. * the feedback becomes user individual.
  1296. *
  1297. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1298. *
  1299. * @version march 2006
  1300. */
  1301. function get_total_number_feedback()
  1302. {
  1303. $course_id = api_get_course_int_id();
  1304. $sql = "SELECT COUNT(feedback_id) AS total, file_id
  1305. FROM ".Database::get_course_table(TABLE_DROPBOX_FEEDBACK)."
  1306. WHERE c_id = $course_id
  1307. GROUP BY file_id";
  1308. $result = Database::query($sql);
  1309. $return = [];
  1310. while ($row = Database::fetch_array($result)) {
  1311. $return[$row['file_id']] = $row['total'];
  1312. }
  1313. return $return;
  1314. }
  1315. /**
  1316. * @desc this function checks if the key exists. If this is the case
  1317. * it returns the value, if not it returns 0
  1318. *
  1319. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1320. *
  1321. * @version march 2006
  1322. */
  1323. function check_number_feedback($key, $array)
  1324. {
  1325. if (is_array($array)) {
  1326. if (array_key_exists($key, $array)) {
  1327. return $array[$key];
  1328. } else {
  1329. return 0;
  1330. }
  1331. } else {
  1332. return 0;
  1333. }
  1334. }
  1335. /**
  1336. * Get the last access to a given tool of a given user.
  1337. *
  1338. * @param $tool string the tool constant
  1339. * @param $courseId the course_id
  1340. * @param $user_id the id of the user
  1341. *
  1342. * @return string last tool access date
  1343. *
  1344. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  1345. *
  1346. * @version march 2006
  1347. *
  1348. * @todo consider moving this function to a more appropriate place.
  1349. */
  1350. function get_last_tool_access($tool, $courseId = null, $user_id = null)
  1351. {
  1352. // The default values of the parameters
  1353. if (empty($courseId)) {
  1354. $courseId = api_get_course_int_id();
  1355. }
  1356. if (empty($user_id)) {
  1357. $user_id = api_get_user_id();
  1358. }
  1359. // the table where the last tool access is stored (=track_e_lastaccess)
  1360. $table_last_access = Database::get_main_table('track_e_lastaccess');
  1361. $sql = "SELECT access_date FROM $table_last_access
  1362. WHERE
  1363. access_user_id = ".intval($user_id)." AND
  1364. c_id='".intval($courseId)."' AND
  1365. access_tool='".Database::escape_string($tool)."'
  1366. ORDER BY access_date DESC
  1367. LIMIT 1";
  1368. $result = Database::query($sql);
  1369. $row = Database::fetch_array($result);
  1370. return $row['access_date'];
  1371. }
  1372. /**
  1373. * Previously $dropbox_cnf['mailingIdBase'], returns a mailing ID to generate a mail ID.
  1374. *
  1375. * @return int
  1376. */
  1377. function get_mail_id_base()
  1378. {
  1379. // false = no mailing functionality
  1380. //$dropbox_cnf['mailingIdBase'] = 10000000; // bigger than any user_id,
  1381. // allowing enough space for pseudo_ids as uploader_id, dest_user_id, user_id:
  1382. // mailing pseudo_id = dropbox_cnf('mailingIdBase') + mailing id
  1383. return 10000000;
  1384. }