dropbox_submit.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /*
  4. * PREVENT RESUBMITING
  5. * This part checks if the $dropbox_unid var has the same ID
  6. * as the session var $dropbox_uniqueid that was registered as a session
  7. * var before.
  8. * The resubmit prevention only works with GET requests, because it gives some annoying
  9. * behaviours with POST requests.
  10. */
  11. /*
  12. if (isset($_POST['dropbox_unid'])) {
  13. $dropbox_unid = $_POST['dropbox_unid'];
  14. } elseif (isset($_GET['dropbox_unid'])) {
  15. $dropbox_unid = $_GET['dropbox_unid'];
  16. } else {
  17. die(get_lang('BadFormData').' (code 400)');
  18. }
  19. if (isset($_SESSION['dropbox_uniqueid']) && isset($_GET['dropbox_unid']) && $dropbox_unid == $_SESSION['dropbox_uniqueid']) {
  20. //resubmit : go to index.php
  21. // only prevent resending of data for GETS, not POSTS because this gives annoying results
  22. if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
  23. $mypath = 'https';
  24. } else {
  25. $mypath = 'http';
  26. }
  27. $mypath = $mypath.'://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/index.php';
  28. header("Location: $mypath");
  29. }
  30. $dropbox_uniqueid = $dropbox_unid;
  31. api_session_register('dropbox_uniqueid');
  32. */
  33. /**
  34. * FORM SUBMIT
  35. * - VALIDATE POSTED DATA
  36. * - UPLOAD NEW FILE
  37. */
  38. if (isset($_POST['submitWork'])) {
  39. require_once api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php';
  40. $error = false;
  41. $errormsg = '';
  42. /**
  43. * FORM SUBMIT : VALIDATE POSTED DATA
  44. */
  45. // the author or description field is empty
  46. if (!isset($_POST['authors']) || !isset( $_POST['description'])) {
  47. $error = true;
  48. $errormsg = get_lang('BadFormData');
  49. } elseif (!isset( $_POST['recipients']) || count( $_POST['recipients']) <= 0) {
  50. $error = true;
  51. $errormsg = get_lang('NoUserSelected');
  52. } else {
  53. $thisIsAMailing = false;
  54. $thisIsJustUpload = false;
  55. foreach ($_POST['recipients'] as $rec) {
  56. if ($rec == 'mailing') {
  57. $thisIsAMailing = true;
  58. } elseif ($rec == 'upload') {
  59. $thisIsJustUpload = true;
  60. } elseif (strpos($rec, 'user_') === 0 && !isCourseMember(substr($rec, strlen('user_')))) {
  61. echo '401';
  62. die(get_lang('BadFormData').' (code 401)');
  63. } elseif (strpos($rec, 'group_') !== 0 && strpos($rec, 'user_') !== 0) {
  64. echo '402';
  65. die(get_lang('BadFormData').' (code 402)');
  66. }
  67. }
  68. // we are doing a mailing but an additional recipient is selected
  69. if ($thisIsAMailing && ( count($_POST['recipients']) != 1)) {
  70. $error = true;
  71. $errormsg = get_lang('MailingSelectNoOther');
  72. }
  73. // we are doing a just upload but an additional recipient is selected.
  74. elseif ( $thisIsJustUpload && ( count($_POST['recipients']) != 1)) {
  75. $error = true;
  76. $errormsg = get_lang('MailingJustUploadSelectNoOther');
  77. } elseif (empty($_FILES['file']['name'])) {
  78. $error = true;
  79. $errormsg = get_lang('NoFileSpecified');
  80. }
  81. }
  82. //check if $_POST['cb_overwrite'] is true or false
  83. $dropbox_overwrite = false;
  84. if (isset($_POST['cb_overwrite']) && $_POST['cb_overwrite']) {
  85. $dropbox_overwrite = true;
  86. }
  87. /**
  88. * FORM SUBMIT : UPLOAD NEW FILE
  89. */
  90. if (!$error) {
  91. $dropbox_filename = $_FILES['file']['name'];
  92. $dropbox_filesize = $_FILES['file']['size'];
  93. $dropbox_filetype = $_FILES['file']['type'];
  94. $dropbox_filetmpname = $_FILES['file']['tmp_name'];
  95. if ($dropbox_filesize <= 0 || $dropbox_filesize > dropbox_cnf('maxFilesize')) {
  96. $errormsg = get_lang('TooBig'); // TODO: The "too big" message does not fit in the case of uploading zero-sized file.
  97. $error = true;
  98. } elseif (!is_uploaded_file($dropbox_filetmpname)) { // check user fraud : no clean error msg.
  99. die(get_lang('BadFormData').' (code 403)');
  100. }
  101. if (!$error) {
  102. // Try to add an extension to the file if it hasn't got one
  103. $dropbox_filename = add_ext_on_mime($dropbox_filename, $dropbox_filetype);
  104. // Replace dangerous characters
  105. $dropbox_filename = replace_dangerous_char($dropbox_filename);
  106. // Transform any .php file in .phps fo security
  107. $dropbox_filename = php2phps($dropbox_filename);
  108. if (!filter_extension($dropbox_filename)) {
  109. $error = true;
  110. $errormsg = get_lang('UplUnableToSaveFileFilteredExtension');
  111. } else {
  112. // set title
  113. $dropbox_title = $dropbox_filename;
  114. // set author
  115. if ($_POST['authors'] == '') {
  116. $_POST['authors'] = getUserNameFromId($_user['user_id']);
  117. }
  118. if ($dropbox_overwrite) {
  119. $dropbox_person = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
  120. foreach ($dropbox_person->sentWork as $w) {
  121. if ($w->title == $dropbox_filename) {
  122. if (($w->recipients[0]['id'] > dropbox_cnf('mailingIdBase')) xor $thisIsAMailing) {
  123. $error = true;
  124. $errormsg = get_lang('MailingNonMailingError');
  125. }
  126. if ( ($w->recipients[0]['id'] == $_user['user_id']) xor $thisIsJustUpload) {
  127. $error = true;
  128. $errormsg = get_lang('MailingJustUploadSelectNoOther');
  129. }
  130. $dropbox_filename = $w->filename;
  131. $found = true;
  132. break;
  133. }
  134. }
  135. } else {
  136. // rename file to login_filename_uniqueId format
  137. $dropbox_filename = getLoginFromId( $_user['user_id']) . '_' . $dropbox_filename . '_'.uniqid('');
  138. }
  139. if (!is_dir(dropbox_cnf('sysPath'))) {
  140. //The dropbox subdir doesn't exist yet so make it and create the .htaccess file
  141. mkdir(dropbox_cnf('sysPath'), api_get_permissions_for_new_directories()) or die(get_lang('ErrorCreatingDir').' (code 404)');
  142. $fp = fopen(dropbox_cnf('sysPath').'/.htaccess', 'w') or die(get_lang('ErrorCreatingDir').' (code 405)');
  143. fwrite($fp, "AuthName AllowLocalAccess
  144. AuthType Basic
  145. order deny,allow
  146. deny from all
  147. php_flag zlib.output_compression off") or die(get_lang('ErrorCreatingDir').' (code 406)');
  148. }
  149. if ($error) {}
  150. elseif ($thisIsAMailing) {
  151. if (preg_match(dropbox_cnf('mailingZipRegexp'), $dropbox_title)) {
  152. $newWorkRecipients = dropbox_cnf('mailingIdBase');
  153. } else {
  154. $error = true;
  155. $errormsg = $dropbox_title . ': ' . get_lang('MailingWrongZipfile');
  156. }
  157. } elseif ($thisIsJustUpload) {
  158. $newWorkRecipients = array();
  159. } else {
  160. // Creating the array that contains all the users who will receive the file
  161. $newWorkRecipients = array();
  162. foreach ($_POST['recipients'] as $rec) {
  163. if (strpos($rec, 'user_') === 0) {
  164. $newWorkRecipients[] = substr($rec, strlen('user_'));
  165. } elseif (strpos($rec, 'group_') === 0) {
  166. $userList = GroupManager::get_subscribed_users(substr($rec, strlen('group_')));
  167. foreach ($userList as $usr) {
  168. if (!in_array($usr['user_id'], $newWorkRecipients) && $usr['user_id'] != $_user['user_id']) {
  169. $newWorkRecipients[] = $usr['user_id'];
  170. }
  171. }
  172. }
  173. }
  174. }
  175. // After uploading the file, create the db entries
  176. if (!$error) {
  177. @move_uploaded_file( $dropbox_filetmpname, dropbox_cnf('sysPath') . '/' . $dropbox_filename)
  178. or die(get_lang('UploadError').' (code 407)');
  179. new Dropbox_SentWork($_user['user_id'], $dropbox_title, $_POST['description'], strip_tags($_POST['authors']), $dropbox_filename, $dropbox_filesize, $newWorkRecipients);
  180. }
  181. }
  182. }
  183. } //end if(!$error)
  184. /**
  185. * SUBMIT FORM RESULTMESSAGE
  186. */
  187. if (!$error) {
  188. $return_message = get_lang('FileUploadSucces');
  189. } else {
  190. $return_message = $errormsg;
  191. }
  192. } // end if ( isset( $_POST['submitWork']))
  193. /**
  194. * EXAMINE OR SEND MAILING (NEW)
  195. */
  196. if (isset($_GET['mailingIndex'])) { // examine or send
  197. $dropbox_person = new Dropbox_Person( $_user['user_id'], $is_courseAdmin, $is_courseTutor);
  198. if (isset($_SESSION['sentOrder'])) {
  199. $dropbox_person->orderSentWork($_SESSION['sentOrder']);
  200. }
  201. $i = $_GET['mailingIndex'];
  202. $mailing_item = $dropbox_person->sentWork[$i];
  203. $mailing_title = $mailing_item->title;
  204. $mailing_file = dropbox_cnf('sysPath') . '/' . $mailing_item->filename;
  205. $errormsg = '<b>' . $mailing_item->recipients[0]['name'] . ' ('
  206. . "<a href='dropbox_download.php?origin=$origin&id=".urlencode($mailing_item->id)."'>"
  207. . htmlspecialchars($mailing_title, ENT_QUOTES, api_get_system_encoding()) . '</a>):</b><br /><br />';
  208. if (preg_match( dropbox_cnf('mailingZipRegexp'), $mailing_title, $nameParts)) {
  209. $var = api_strtoupper($nameParts[2]); // the variable part of the name
  210. $course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  211. $sel = "SELECT u.user_id, u.lastname, u.firstname, cu.status
  212. FROM `".$_configuration['main_database']."`.`user` u
  213. LEFT JOIN $course_user cu
  214. ON cu.user_id = u.user_id AND cu.relation_type<>".COURSE_RELATION_TYPE_RRHH." AND cu.course_code = '".$_course['sysCode']."'";
  215. $sel .= " WHERE u.".dropbox_cnf("mailingWhere".$var)." = '";
  216. function getUser($thisRecip) {
  217. // string result = error message, array result = [user_id, lastname, firstname]
  218. global $var, $sel;
  219. if (isset($students)) {
  220. unset($students);
  221. }
  222. $result = Database::query($sel . $thisRecip . "'");
  223. while ( ($res = Database::fetch_array($result))) {$students[] = $res;}
  224. Database::free_result($result);
  225. if (count($students) == 1) {
  226. return($students[0]);
  227. } elseif (count($students) > 1) {
  228. return ' <'.get_lang('MailingFileRecipDup', '').$var."= $thisRecip>";
  229. } else {
  230. return ' <'.get_lang('MailingFileRecipNotFound', '').$var."= $thisRecip>";
  231. }
  232. }
  233. $preFix = $nameParts[1]; $postFix = $nameParts[3];
  234. $preLen = api_strlen($preFix); $postLen = api_strlen($postFix);
  235. function findRecipient($thisFile) {
  236. // string result = error message, array result = [user_id, lastname, firstname, status]
  237. global $nameParts, $preFix, $preLen, $postFix, $postLen;
  238. if (preg_match(dropbox_cnf('mailingFileRegexp'), $thisFile, $matches)) {
  239. $thisName = $matches[1];
  240. if (api_substr($thisName, 0, $preLen) == $preFix) {
  241. if ($postLen == 0 || api_substr($thisName, -$postLen) == $postFix) {
  242. $thisRecip = api_substr($thisName, $preLen, api_strlen($thisName) - $preLen - $postLen);
  243. if ($thisRecip) {
  244. return getUser($thisRecip);
  245. }
  246. return ' <'.get_lang('MailingFileNoRecip', '').'>';
  247. } else {
  248. return ' <'.get_lang('MailingFileNoPostfix', '').$postFix.'>';
  249. }
  250. } else {
  251. return ' <'.get_lang('MailingFileNoPrefix', '').$preFix.'>';
  252. }
  253. } else {
  254. return ' <'.get_lang('MailingFileFunny', '').'>';
  255. }
  256. }
  257. require api_get_path(LIBRARY_PATH) . 'pclzip/pclzip.lib.php';
  258. $zipFile = new pclZip($mailing_file);
  259. $goodFiles = array();
  260. $zipContent = $zipFile->listContent();
  261. $ucaseFiles = array();
  262. if ($zipContent) {
  263. foreach( $zipFile->listContent() as $thisContent) {
  264. $thisFile = substr(strrchr('/' . $thisContent['filename'], '/'), 1);
  265. $thisFileUcase = strtoupper($thisFile);
  266. if (preg_match("~.(php.*|phtml)$~i", $thisFile)) {
  267. $error = true;
  268. $errormsg .= $thisFile . ': ' . get_lang('MailingZipPhp');
  269. break;
  270. } elseif (!$thisContent['folder']) {
  271. if ($ucaseFiles[$thisFileUcase]) {
  272. $error = true;
  273. $errormsg .= $thisFile . ': ' . get_lang('MailingZipDups');
  274. break;
  275. } else {
  276. $goodFiles[$thisFile] = findRecipient($thisFile);
  277. $ucaseFiles[$thisFileUcase] = 'yep';
  278. }
  279. }
  280. }
  281. } else {
  282. $error = true;
  283. $errormsg .= get_lang('MailingZipEmptyOrCorrupt');
  284. }
  285. if (!$error) {
  286. $students = array(); // collect all recipients in this course
  287. foreach ($goodFiles as $thisFile => $thisRecip) {
  288. $errormsg .= htmlspecialchars($thisFile, ENT_QUOTES, api_get_system_encoding()) . ': ';
  289. if (is_string($thisRecip)) { // see findRecipient
  290. $errormsg .= '<font color="#FF0000">'
  291. . htmlspecialchars($thisRecip, ENT_QUOTES, api_get_system_encoding()) . '</font><br />';
  292. } else {
  293. if ( isset( $_GET['mailingSend'])) {
  294. $errormsg .= get_lang('MailingFileSentTo');
  295. } else {
  296. $errormsg .= get_lang('MailingFileIsFor');
  297. }
  298. $errormsg .= htmlspecialchars(api_get_person_name($thisRecip[2], $thisRecip[1]), ENT_QUOTES, api_get_system_encoding());
  299. if (is_null($thisRecip[3])) {
  300. $errormsg .= get_lang('MailingFileNotRegistered');
  301. } else {
  302. $students[] = $thisRecip[0];
  303. }
  304. $errormsg .= '<br />';
  305. }
  306. }
  307. // find student course members not among the recipients
  308. $course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
  309. $sql = "SELECT u.lastname, u.firstname
  310. FROM $course_user cu
  311. LEFT JOIN `".$_configuration['main_database']."`.`user` u
  312. ON cu.user_id = u.user_id AND cu.course_code = '".$_course['sysCode']."'
  313. WHERE cu.status = 5
  314. AND u.user_id NOT IN ('" . implode("', '" , $students) . "')";
  315. $result = Database::query($sql);
  316. if (Database::num_rows($result) > 0) {
  317. $remainingUsers = '';
  318. while ($res = Database::fetch_array($result)) {
  319. $remainingUsers .= ', ' . htmlspecialchars(api_get_person_name($res[1], $res[0]), ENT_QUOTES, api_get_system_encoding());
  320. }
  321. $errormsg .= '<br />' . get_lang('MailingNothingFor') . api_substr($remainingUsers, 1) . '.<br />';
  322. }
  323. if (isset($_GET['mailingSend'])) {
  324. chdir(dropbox_cnf('sysPath'));
  325. $zipFile->extract(PCLZIP_OPT_REMOVE_ALL_PATH);
  326. $mailingPseudoId = dropbox_cnf('mailingIdBase') + $mailing_item->id;
  327. foreach ($goodFiles as $thisFile => $thisRecip) {
  328. if (is_string($thisRecip)) { // remove problem file
  329. @unlink(dropbox_cnf('sysPath') . '/' . $thisFile);
  330. } else {
  331. $newName = getLoginFromId( $_user['user_id']) . '_' . $thisFile . '_' . uniqid('');
  332. if (rename(dropbox_cnf('sysPath') . '/' . $thisFile, dropbox_cnf('sysPath') . '/' . $newName))
  333. new Dropbox_SentWork($mailingPseudoId, $thisFile, $mailing_item->description, $mailing_item->author, $newName, $thisContent['size'], array($thisRecip[0]));
  334. }
  335. }
  336. $sendDT = addslashes(date('Y-m-d H:i:s', time()));
  337. // set filesize to zero on send, to avoid 2nd send (see index.php)
  338. $sql = "UPDATE ".dropbox_cnf("tbl_file")."
  339. SET filesize = '0'
  340. , upload_date = '".$sendDT."', last_upload_date = '".$sendDT."'
  341. WHERE id='".addslashes($mailing_item->id)."'";
  342. $result = Database::query($sql);
  343. } elseif ($mailing_item->filesize != 0) {
  344. $errormsg .= '<br />' . get_lang('MailingNotYetSent') . '<br />';
  345. }
  346. }
  347. } else {
  348. $error = true;
  349. $errormsg .= get_lang('MailingWrongZipfile');
  350. }
  351. /**
  352. * EXAMINE OR SEND MAILING RESULTMESSAGE
  353. */
  354. if ($error) {
  355. ?>
  356. <b><font color="#FF0000"><?php echo $errormsg?></font></b><br /><br />
  357. <a href="index.php<?php echo "?origin=$origin"; ?>"><?php echo get_lang('BackList'); ?></a><br />
  358. <?php
  359. } else {
  360. ?>
  361. <?php echo $errormsg?><br /><br />
  362. <a href="index.php<?php echo "?origin=$origin"; ?>"><?php echo get_lang('BackList'); ?></a><br />
  363. <?php
  364. }
  365. }
  366. /**
  367. * DELETE RECEIVED OR SENT FILES - EDIT FEEDBACK
  368. * - DELETE ALL RECEIVED FILES
  369. * - DELETE 1 RECEIVED FILE
  370. * - DELETE ALL SENT FILES
  371. * - DELETE 1 SENT FILE
  372. * - EDIT FEEDBACK
  373. */
  374. if (isset($_GET['deleteReceived']) || isset($_GET['deleteSent'])
  375. || isset( $_GET['showFeedback']) || isset( $_GET['editFeedback'])) {
  376. if ($_GET['mailing']) {
  377. getUserOwningThisMailing($_GET['mailing'], $_user['user_id'], '408');
  378. $dropbox_person = new Dropbox_Person($_GET['mailing'], $is_courseAdmin, $is_courseTutor);
  379. } else {
  380. $dropbox_person = new Dropbox_Person($_user['user_id'], $is_courseAdmin, $is_courseTutor);
  381. }
  382. if (isset($_SESSION['sentOrder'])) {
  383. $dropbox_person->orderSentWork($_SESSION['sentOrder']);
  384. }
  385. if (isset($_SESSION['receivedOrder'])) {
  386. $dropbox_person->orderReceivedWork($_SESSION['receivedOrder']);
  387. }
  388. /*if (!$dropbox_person->isCourseAdmin || ! $dropbox_person->isCourseTutor) {
  389. die(get_lang('GeneralError').' (code 408)');
  390. }*/
  391. $tellUser = get_lang('FileDeleted');
  392. if (isset($_GET['deleteReceived'])) {
  393. if ($_GET['deleteReceived'] == 'all') {
  394. $dropbox_person->deleteAllReceivedWork();
  395. } elseif (is_numeric($_GET['deleteReceived'])) {
  396. $dropbox_person->deleteReceivedWork( $_GET['deleteReceived']);
  397. } else {
  398. die(get_lang('GeneralError').' (code 409)');
  399. }
  400. } elseif (isset( $_GET['deleteSent'])) {
  401. if ($_GET['deleteSent'] == 'all') {
  402. $dropbox_person->deleteAllSentWork( );
  403. } elseif (is_numeric($_GET['deleteSent'])) {
  404. $dropbox_person->deleteSentWork($_GET['deleteSent']);
  405. } else {
  406. die(get_lang('GeneralError').' (code 410)');
  407. }
  408. } elseif (isset($_GET['showFeedback'])) {
  409. $w = new Dropbox_SentWork($id = $_GET['showFeedback']);
  410. if ($w->uploader_id != $_user['user_id']) {
  411. getUserOwningThisMailing($w->uploader_id, $_user['user_id'], '411');
  412. }
  413. foreach ($w -> recipients as $r) {
  414. if (($fb = $r['feedback'])) {
  415. $fbarray[$r['feedback_date'].$r['name']] = $r['name'].' '.get_lang('SentOn', '').' '.$r['feedback_date'].":\n".$fb;
  416. }
  417. }
  418. if ($fbarray) {
  419. krsort($fbarray);
  420. echo '<textarea class="dropbox_feedbacks">',
  421. htmlspecialchars(implode("\n\n", $fbarray), ENT_QUOTES, api_get_system_encoding()), '</textarea>', "\n";
  422. } else {
  423. echo '<textarea class="dropbox_feedbacks">&nbsp;</textarea>', "\n";
  424. }
  425. $tellUser = get_lang('ShowFeedback');
  426. } else { // if ( isset( $_GET['editFeedback'])) {
  427. $id = $_GET['editFeedback'];
  428. $found = false;
  429. foreach ($dropbox_person->receivedWork as $w) {
  430. if ($w->id == $id) {
  431. $found = true;
  432. break;
  433. }
  434. }
  435. if (!$found) die(get_lang('GeneralError').' (code 415)');
  436. echo '<form method="post" action="index.php">', "\n",
  437. '<input type="hidden" name="feedbackid" value="',
  438. $id, '"/>', "\n",
  439. '<textarea name="feedbacktext" class="dropbox_feedbacks">',
  440. htmlspecialchars($w->feedback, ENT_QUOTES, api_get_system_encoding()), '</textarea>', "<br />\n",
  441. '<input type="submit" name="feedbacksubmit" value="', get_lang('Ok', ''), '"/>', "\n",
  442. '</form>', "\n";
  443. $tellUser = get_lang('GiveFeedback');
  444. }
  445. /**
  446. * RESULTMESSAGE FOR DELETE FILE OR EDIT FEEDBACK
  447. */
  448. $return_message = get_lang('BackList');
  449. }