PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/file/file.controller.php

https://github.com/prologos/xe-core
PHP | 927 lines | 551 code | 111 blank | 265 comment | 137 complexity | 652043ef798581583dfb4f29aa4ac71c MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /* Copyright (C) NAVER <http://www.navercorp.com> */
  3. /**
  4. * Controller class of the file module
  5. * @author NAVER (developers@xpressengine.com)
  6. */
  7. class fileController extends file
  8. {
  9. /**
  10. * Initialization
  11. * @return void
  12. */
  13. function init()
  14. {
  15. }
  16. /**
  17. * Upload attachments in the editor
  18. *
  19. * Determine the upload target srl from editor_sequence and uploadTargetSrl variables.
  20. * Create and return the UploadTargetSrl if not exists so that UI can use the value
  21. * for sync.
  22. *
  23. * @return void
  24. */
  25. function procFileUpload()
  26. {
  27. $file_info = Context::get('Filedata');
  28. // An error appears if not a normally uploaded file
  29. if(!is_uploaded_file($file_info['tmp_name'])) exit();
  30. // Basic variables setting
  31. $oFileModel = getModel('file');
  32. $editor_sequence = Context::get('editor_sequence');
  33. $upload_target_srl = intval(Context::get('uploadTargetSrl'));
  34. if(!$upload_target_srl) $upload_target_srl = intval(Context::get('upload_target_srl'));
  35. $module_srl = $this->module_srl;
  36. // Exit a session if there is neither upload permission nor information
  37. if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit();
  38. // Extract from session information if upload_target_srl is not specified
  39. if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl;
  40. // Create if upload_target_srl is not defined in the session information
  41. if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence();
  42. return $this->insertFile($file_info, $module_srl, $upload_target_srl);
  43. }
  44. /**
  45. * Iframe upload attachments
  46. *
  47. * @return Object
  48. */
  49. function procFileIframeUpload()
  50. {
  51. // Basic variables setting
  52. $editor_sequence = Context::get('editor_sequence');
  53. $callback = Context::get('callback');
  54. $module_srl = $this->module_srl;
  55. $upload_target_srl = intval(Context::get('uploadTargetSrl'));
  56. if(!$upload_target_srl) $upload_target_srl = intval(Context::get('upload_target_srl'));
  57. // Exit a session if there is neither upload permission nor information
  58. if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit();
  59. // Extract from session information if upload_target_srl is not specified
  60. if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl;
  61. // Create if upload_target_srl is not defined in the session information
  62. if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence();
  63. // Delete and then attempt to re-upload if file_srl is requested
  64. $file_srl = Context::get('file_srl');
  65. if($file_srl) $this->deleteFile($file_srl);
  66. $file_info = Context::get('Filedata');
  67. // An error appears if not a normally uploaded file
  68. if(is_uploaded_file($file_info['tmp_name'])) {
  69. $output = $this->insertFile($file_info, $module_srl, $upload_target_srl);
  70. Context::set('uploaded_fileinfo',$output);
  71. }
  72. Context::set('layout','none');
  73. $this->setTemplatePath($this->module_path.'tpl');
  74. $this->setTemplateFile('iframe');
  75. }
  76. /**
  77. * Image resize
  78. *
  79. * @return Object
  80. */
  81. function procFileImageResize()
  82. {
  83. $file_srl = Context::get('file_srl');
  84. $width = Context::get('width');
  85. $height = Context::get('height');
  86. if(!$file_srl || !$width)
  87. {
  88. return new Object(-1,'msg_invalid_request');
  89. }
  90. $oFileModel = getModel('file');
  91. $fileInfo = $oFileModel->getFile($file_srl);
  92. if(!$fileInfo || $fileInfo->direct_download != 'Y')
  93. {
  94. return new Object(-1,'msg_invalid_request');
  95. }
  96. $source_src = $fileInfo->uploaded_filename;
  97. $output_src = $source_src . '.resized' . strrchr($source_src,'.');
  98. $type = 'ratio';
  99. if(!$height) $height = $width-1;
  100. if(FileHandler::createImageFile($source_src,$output_src,$width,$height,'','ratio'))
  101. {
  102. $output->info = getimagesize($output_src);
  103. $output->src = $output_src;
  104. }
  105. else
  106. {
  107. return new Object(-1,'msg_invalid_request');
  108. }
  109. $this->add('resized_info',$output);
  110. }
  111. /**
  112. * Download Attachment
  113. *
  114. * <pre>
  115. * Receive a request directly
  116. * file_srl: File sequence
  117. * sid : value in DB for comparison, No download if not matched
  118. *
  119. * This method call trigger 'file.downloadFile'.
  120. * before, after.
  121. * Trigger object contains:
  122. * - download_url
  123. * - file_srl
  124. * - upload_target_srl
  125. * - upload_target_type
  126. * - sid
  127. * - module_srl
  128. * - member_srl
  129. * - download_count
  130. * - direct_download
  131. * - source_filename
  132. * - uploaded_filename
  133. * - file_size
  134. * - comment
  135. * - isvalid
  136. * - regdate
  137. * - ipaddress
  138. * </pre>
  139. *
  140. * return void
  141. */
  142. function procFileDownload()
  143. {
  144. $oFileModel = getModel('file');
  145. if(isset($this->grant->access) && $this->grant->access !== true) return new Object(-1, 'msg_not_permitted');
  146. $file_srl = Context::get('file_srl');
  147. $sid = Context::get('sid');
  148. $logged_info = Context::get('logged_info');
  149. // Get file information from the DB
  150. $columnList = array('file_srl', 'sid', 'isvalid', 'source_filename', 'module_srl', 'uploaded_filename', 'file_size', 'member_srl', 'upload_target_srl', 'upload_target_type');
  151. $file_obj = $oFileModel->getFile($file_srl, $columnList);
  152. // If the requested file information is incorrect, an error that file cannot be found appears
  153. if($file_obj->file_srl!=$file_srl || $file_obj->sid!=$sid) return $this->stop('msg_file_not_found');
  154. // Notify that file download is not allowed when standing-by(Only a top-administrator is permitted)
  155. if($logged_info->is_admin != 'Y' && $file_obj->isvalid!='Y') return $this->stop('msg_not_permitted_download');
  156. // File name
  157. $filename = $file_obj->source_filename;
  158. $file_module_config = $oFileModel->getFileModuleConfig($file_obj->module_srl);
  159. // Not allow the file outlink
  160. if($file_module_config->allow_outlink == 'N')
  161. {
  162. // Handles extension to allow outlink
  163. if($file_module_config->allow_outlink_format)
  164. {
  165. $allow_outlink_format_array = array();
  166. $allow_outlink_format_array = explode(',', $file_module_config->allow_outlink_format);
  167. if(!is_array($allow_outlink_format_array)) $allow_outlink_format_array[0] = $file_module_config->allow_outlink_format;
  168. foreach($allow_outlink_format_array as $val)
  169. {
  170. $val = trim($val);
  171. if(preg_match("/\.{$val}$/i", $filename))
  172. {
  173. $file_module_config->allow_outlink = 'Y';
  174. break;
  175. }
  176. }
  177. }
  178. // Sites that outlink is allowed
  179. if($file_module_config->allow_outlink != 'Y')
  180. {
  181. $referer = parse_url($_SERVER["HTTP_REFERER"]);
  182. if($referer['host'] != $_SERVER['HTTP_HOST'])
  183. {
  184. if($file_module_config->allow_outlink_site)
  185. {
  186. $allow_outlink_site_array = array();
  187. $allow_outlink_site_array = explode("\n", $file_module_config->allow_outlink_site);
  188. if(!is_array($allow_outlink_site_array)) $allow_outlink_site_array[0] = $file_module_config->allow_outlink_site;
  189. foreach($allow_outlink_site_array as $val)
  190. {
  191. $site = parse_url(trim($val));
  192. if($site['host'] == $referer['host'])
  193. {
  194. $file_module_config->allow_outlink = 'Y';
  195. break;
  196. }
  197. }
  198. }
  199. }
  200. else $file_module_config->allow_outlink = 'Y';
  201. }
  202. if($file_module_config->allow_outlink != 'Y') return $this->stop('msg_not_allowed_outlink');
  203. }
  204. // Check if a permission for file download is granted
  205. $downloadGrantCount = 0;
  206. if(is_array($file_module_config->download_grant))
  207. {
  208. foreach($file_module_config->download_grant AS $value)
  209. if($value) $downloadGrantCount++;
  210. }
  211. if(is_array($file_module_config->download_grant) && $downloadGrantCount>0)
  212. {
  213. if(!Context::get('is_logged')) return $this->stop('msg_not_permitted_download');
  214. $logged_info = Context::get('logged_info');
  215. if($logged_info->is_admin != 'Y')
  216. {
  217. $oModuleModel =& getModel('module');
  218. $columnList = array('module_srl', 'site_srl');
  219. $module_info = $oModuleModel->getModuleInfoByModuleSrl($file_obj->module_srl, $columnList);
  220. if(!$oModuleModel->isSiteAdmin($logged_info, $module_info->site_srl))
  221. {
  222. $oMemberModel =& getModel('member');
  223. $member_groups = $oMemberModel->getMemberGroups($logged_info->member_srl, $module_info->site_srl);
  224. $is_permitted = false;
  225. for($i=0;$i<count($file_module_config->download_grant);$i++)
  226. {
  227. $group_srl = $file_module_config->download_grant[$i];
  228. if($member_groups[$group_srl])
  229. {
  230. $is_permitted = true;
  231. break;
  232. }
  233. }
  234. if(!$is_permitted) return $this->stop('msg_not_permitted_download');
  235. }
  236. }
  237. }
  238. // Call a trigger (before)
  239. $output = ModuleHandler::triggerCall('file.downloadFile', 'before', $file_obj);
  240. if(!$output->toBool()) return $this->stop(($output->message)?$output->message:'msg_not_permitted_download');
  241. // 다운로드 후 (가상)
  242. // Increase download_count
  243. $args = new stdClass();
  244. $args->file_srl = $file_srl;
  245. executeQuery('file.updateFileDownloadCount', $args);
  246. // Call a trigger (after)
  247. $output = ModuleHandler::triggerCall('file.downloadFile', 'after', $file_obj);
  248. $file_key = $_SESSION['__XE_FILE_KEY__'][$file_srl] = hash('md5',rand());
  249. header('Location: '.getNotEncodedUrl('', 'act', 'procFileOutput','file_srl',$file_srl,'file_key',$file_key));
  250. Context::close();
  251. exit();
  252. }
  253. public function procFileOutput()
  254. {
  255. $oFileModel = getModel('file');
  256. $file_srl = Context::get('file_srl');
  257. $file_key = Context::get('file_key');
  258. if(strstr($_SERVER['HTTP_USER_AGENT'], "Android")) $is_android = true;
  259. if($is_android && $_SESSION['__XE_FILE_KEY_AND__'][$file_srl]) $session_key = '__XE_FILE_KEY_AND__';
  260. else $session_key = '__XE_FILE_KEY__';
  261. $columnList = array('source_filename', 'uploaded_filename', 'file_size');
  262. $file_obj = $oFileModel->getFile($file_srl, $columnList);
  263. $uploaded_filename = $file_obj->uploaded_filename;
  264. if(!file_exists($uploaded_filename)) return $this->stop('msg_file_not_found');
  265. if(!$file_key || $_SESSION[$session_key][$file_srl] != $file_key)
  266. {
  267. unset($_SESSION[$session_key][$file_srl]);
  268. return $this->stop('msg_invalid_request');
  269. }
  270. $file_size = $file_obj->file_size;
  271. $filename = $file_obj->source_filename;
  272. if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE || (strpos($_SERVER['HTTP_USER_AGENT'], 'Windows') !== FALSE && strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== FALSE && strpos($_SERVER['HTTP_USER_AGENT'], 'rv:') !== FALSE))
  273. {
  274. $filename = rawurlencode($filename);
  275. $filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
  276. }
  277. if($is_android)
  278. {
  279. if($_SESSION['__XE_FILE_KEY__'][$file_srl]) $_SESSION['__XE_FILE_KEY_AND__'][$file_srl] = $file_key;
  280. }
  281. unset($_SESSION[$session_key][$file_srl]);
  282. Context::close();
  283. $fp = fopen($uploaded_filename, 'rb');
  284. if(!$fp) return $this->stop('msg_file_not_found');
  285. header("Cache-Control: ");
  286. header("Pragma: ");
  287. header("Content-Type: application/octet-stream");
  288. header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  289. header("Content-Length: " .(string)($file_size));
  290. header('Content-Disposition: attachment; filename="'.$filename.'"');
  291. header("Content-Transfer-Encoding: binary\n");
  292. // if file size is lager than 10MB, use fread function (#18675748)
  293. if(filesize($uploaded_filename) > 1024 * 1024)
  294. {
  295. while(!feof($fp)) echo fread($fp, 1024);
  296. fclose($fp);
  297. }
  298. else
  299. {
  300. fpassthru($fp);
  301. }
  302. exit();
  303. }
  304. /**
  305. * Delete an attachment from the editor
  306. *
  307. * @return Object
  308. */
  309. function procFileDelete()
  310. {
  311. // Basic variable setting(upload_target_srl and module_srl set)
  312. $editor_sequence = Context::get('editor_sequence');
  313. $file_srl = Context::get('file_srl');
  314. $file_srls = Context::get('file_srls');
  315. if($file_srls) $file_srl = $file_srls;
  316. // Exit a session if there is neither upload permission nor information
  317. if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit();
  318. $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl;
  319. $logged_info = Context::get('logged_info');
  320. $oFileModel = getModel('file');
  321. $srls = explode(',',$file_srl);
  322. if(!count($srls)) return;
  323. for($i=0;$i<count($srls);$i++)
  324. {
  325. $srl = (int)$srls[$i];
  326. if(!$srl) continue;
  327. $args = new stdClass;
  328. $args->file_srl = $srl;
  329. $output = executeQuery('file.getFile', $args);
  330. if(!$output->toBool()) continue;
  331. $file_info = $output->data;
  332. if(!$file_info) continue;
  333. $file_grant = $oFileModel->getFileGrant($file_info, $logged_info);
  334. if(!$file_grant->is_deletable) continue;
  335. if($upload_target_srl && $file_srl) $output = $this->deleteFile($file_srl);
  336. }
  337. }
  338. /**
  339. * get file list
  340. *
  341. * @return Object
  342. */
  343. function procFileGetList()
  344. {
  345. if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted');
  346. $fileSrls = Context::get('file_srls');
  347. if($fileSrls) $fileSrlList = explode(',', $fileSrls);
  348. global $lang;
  349. if(count($fileSrlList) > 0)
  350. {
  351. $oFileModel = getModel('file');
  352. $fileList = $oFileModel->getFile($fileSrlList);
  353. if(!is_array($fileList)) $fileList = array($fileList);
  354. if(is_array($fileList))
  355. {
  356. foreach($fileList AS $key=>$value)
  357. {
  358. $value->human_file_size = FileHandler::filesize($value->file_size);
  359. if($value->isvalid=='Y') $value->validName = $lang->is_valid;
  360. else $value->validName = $lang->is_stand_by;
  361. }
  362. }
  363. }
  364. else
  365. {
  366. $fileList = array();
  367. $this->setMessage($lang->no_files);
  368. }
  369. $this->add('file_list', $fileList);
  370. }
  371. /**
  372. * A trigger to return numbers of attachments in the upload_target_srl (document_srl)
  373. *
  374. * @param object $obj Trigger object
  375. * @return Object
  376. */
  377. function triggerCheckAttached(&$obj)
  378. {
  379. $document_srl = $obj->document_srl;
  380. if(!$document_srl) return new Object();
  381. // Get numbers of attachments
  382. $oFileModel = getModel('file');
  383. $obj->uploaded_count = $oFileModel->getFilesCount($document_srl);
  384. return new Object();
  385. }
  386. /**
  387. * A trigger to link the attachment with the upload_target_srl (document_srl)
  388. *
  389. * @param object $obj Trigger object
  390. * @return Object
  391. */
  392. function triggerAttachFiles(&$obj)
  393. {
  394. $document_srl = $obj->document_srl;
  395. if(!$document_srl) return new Object();
  396. $output = $this->setFilesValid($document_srl);
  397. if(!$output->toBool()) return $output;
  398. return new Object();
  399. }
  400. /**
  401. * A trigger to delete the attachment in the upload_target_srl (document_srl)
  402. *
  403. * @param object $obj Trigger object
  404. * @return Object
  405. */
  406. function triggerDeleteAttached(&$obj)
  407. {
  408. $document_srl = $obj->document_srl;
  409. if(!$document_srl) return new Object();
  410. $output = $this->deleteFiles($document_srl);
  411. return $output;
  412. }
  413. /**
  414. * A trigger to return numbers of attachments in the upload_target_srl (comment_srl)
  415. *
  416. * @param object $obj Trigger object
  417. * @return Object
  418. */
  419. function triggerCommentCheckAttached(&$obj)
  420. {
  421. $comment_srl = $obj->comment_srl;
  422. if(!$comment_srl) return new Object();
  423. // Get numbers of attachments
  424. $oFileModel = getModel('file');
  425. $obj->uploaded_count = $oFileModel->getFilesCount($comment_srl);
  426. return new Object();
  427. }
  428. /**
  429. * A trigger to link the attachment with the upload_target_srl (comment_srl)
  430. *
  431. * @param object $obj Trigger object
  432. * @return Object
  433. */
  434. function triggerCommentAttachFiles(&$obj)
  435. {
  436. $comment_srl = $obj->comment_srl;
  437. $uploaded_count = $obj->uploaded_count;
  438. if(!$comment_srl || !$uploaded_count) return new Object();
  439. $output = $this->setFilesValid($comment_srl);
  440. if(!$output->toBool()) return $output;
  441. return new Object();
  442. }
  443. /**
  444. * A trigger to delete the attachment in the upload_target_srl (comment_srl)
  445. *
  446. * @param object $obj Trigger object
  447. * @return Object
  448. */
  449. function triggerCommentDeleteAttached(&$obj)
  450. {
  451. $comment_srl = $obj->comment_srl;
  452. if(!$comment_srl) return new Object();
  453. if($obj->isMoveToTrash) return new Object();
  454. $output = $this->deleteFiles($comment_srl);
  455. return $output;
  456. }
  457. /**
  458. * A trigger to delete all the attachements when deleting the module
  459. *
  460. * @param object $obj Trigger object
  461. * @return Object
  462. */
  463. function triggerDeleteModuleFiles(&$obj)
  464. {
  465. $module_srl = $obj->module_srl;
  466. if(!$module_srl) return new Object();
  467. $oFileController = getAdminController('file');
  468. return $oFileController->deleteModuleFiles($module_srl);
  469. }
  470. /**
  471. * Upload enabled
  472. *
  473. * @param int $editor_sequence
  474. * @param int $upload_target_srl
  475. * @return void
  476. */
  477. function setUploadInfo($editor_sequence, $upload_target_srl=0)
  478. {
  479. if(!isset($_SESSION['upload_info'][$editor_sequence]))
  480. {
  481. $_SESSION['upload_info'][$editor_sequence] = new stdClass();
  482. }
  483. $_SESSION['upload_info'][$editor_sequence]->enabled = true;
  484. $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl;
  485. }
  486. /**
  487. * Set the attachements of the upload_target_srl to be valid
  488. * By changing its state to valid when a document is inserted, it prevents from being considered as a unnecessary file
  489. *
  490. * @param int $upload_target_srl
  491. * @return Object
  492. */
  493. function setFilesValid($upload_target_srl)
  494. {
  495. $args = new stdClass();
  496. $args->upload_target_srl = $upload_target_srl;
  497. return executeQuery('file.updateFileValid', $args);
  498. }
  499. /**
  500. * Add an attachement
  501. *
  502. * <pre>
  503. * This method call trigger 'file.insertFile'.
  504. *
  505. * Before trigger object contains:
  506. * - module_srl
  507. * - upload_target_srl
  508. *
  509. * After trigger object contains:
  510. * - file_srl
  511. * - upload_target_srl
  512. * - module_srl
  513. * - direct_download
  514. * - source_filename
  515. * - uploaded_filename
  516. * - donwload_count
  517. * - file_size
  518. * - comment
  519. * - member_srl
  520. * - sid
  521. * </pre>
  522. *
  523. * @param object $file_info PHP file information array
  524. * @param int $module_srl Sequence of module to upload file
  525. * @param int $upload_target_srl Sequence of target to upload file
  526. * @param int $download_count Initial download count
  527. * @param bool $manual_insert If set true, pass validation check
  528. * @return Object
  529. */
  530. function insertFile($file_info, $module_srl, $upload_target_srl, $download_count = 0, $manual_insert = false)
  531. {
  532. // Call a trigger (before)
  533. $trigger_obj = new stdClass;
  534. $trigger_obj->module_srl = $module_srl;
  535. $trigger_obj->upload_target_srl = $upload_target_srl;
  536. $output = ModuleHandler::triggerCall('file.insertFile', 'before', $trigger_obj);
  537. if(!$output->toBool()) return $output;
  538. // A workaround for Firefox upload bug
  539. if(preg_match('/^=\?UTF-8\?B\?(.+)\?=$/i', $file_info['name'], $match))
  540. {
  541. $file_info['name'] = base64_decode(strtr($match[1], ':', '/'));
  542. }
  543. if(!$manual_insert)
  544. {
  545. // Get the file configurations
  546. $logged_info = Context::get('logged_info');
  547. if($logged_info->is_admin != 'Y')
  548. {
  549. $oFileModel = getModel('file');
  550. $config = $oFileModel->getFileConfig($module_srl);
  551. $allowed_filesize = $config->allowed_filesize * 1024 * 1024;
  552. $allowed_attach_size = $config->allowed_attach_size * 1024 * 1024;
  553. // An error appears if file size exceeds a limit
  554. if($allowed_filesize < filesize($file_info['tmp_name'])) return new Object(-1, 'msg_exceeds_limit_size');
  555. // Get total file size of all attachements (from DB)
  556. $size_args = new stdClass;
  557. $size_args->upload_target_srl = $upload_target_srl;
  558. $output = executeQuery('file.getAttachedFileSize', $size_args);
  559. $attached_size = (int)$output->data->attached_size + filesize($file_info['tmp_name']);
  560. if($attached_size > $allowed_attach_size) return new Object(-1, 'msg_exceeds_limit_size');
  561. }
  562. }
  563. // Set upload path by checking if the attachement is an image or other kinds of file
  564. if(preg_match("/\.(jpe?g|gif|png|wm[va]|mpe?g|avi|swf|flv|mp[1-4]|as[fx]|wav|midi?|moo?v|qt|r[am]{1,2}|m4v)$/i", $file_info['name']))
  565. {
  566. // Immediately remove the direct file if it has any kind of extensions for hacking
  567. $file_info['name'] = preg_replace('/\.(php|phtm|phar|html?|cgi|pl|exe|jsp|asp|inc)/i', '$0-x',$file_info['name']);
  568. $file_info['name'] = str_replace(array('<','>'),array('%3C','%3E'),$file_info['name']);
  569. $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3));
  570. // special character to '_'
  571. // change to md5 file name. because window php bug. window php is not recognize unicode character file name - by cherryfilter
  572. $ext = substr(strrchr($file_info['name'],'.'),1);
  573. //$_filename = preg_replace('/[#$&*?+%"\']/', '_', $file_info['name']);
  574. $_filename = md5(crypt(rand(1000000,900000), rand(0,100))).'.'.$ext;
  575. $filename = $path.$_filename;
  576. $idx = 1;
  577. while(file_exists($filename))
  578. {
  579. $filename = $path.preg_replace('/\.([a-z0-9]+)$/i','_'.$idx.'.$1',$_filename);
  580. $idx++;
  581. }
  582. $direct_download = 'Y';
  583. }
  584. else
  585. {
  586. $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3));
  587. $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100)));
  588. $direct_download = 'N';
  589. }
  590. // Create a directory
  591. if(!FileHandler::makeDir($path)) return new Object(-1,'msg_not_permitted_create');
  592. // Check uploaded file
  593. if(!checkUploadedFile($file_info['tmp_name'])) return new Object(-1,'msg_file_upload_error');
  594. // Move the file
  595. if($manual_insert)
  596. {
  597. @copy($file_info['tmp_name'], $filename);
  598. if(!file_exists($filename))
  599. {
  600. $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext;
  601. @copy($file_info['tmp_name'], $filename);
  602. }
  603. }
  604. else
  605. {
  606. if(!@move_uploaded_file($file_info['tmp_name'], $filename))
  607. {
  608. $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext;
  609. if(!@move_uploaded_file($file_info['tmp_name'], $filename)) return new Object(-1,'msg_file_upload_error');
  610. }
  611. }
  612. // Get member information
  613. $oMemberModel = getModel('member');
  614. $member_srl = $oMemberModel->getLoggedMemberSrl();
  615. // List file information
  616. $args = new stdClass;
  617. $args->file_srl = getNextSequence();
  618. $args->upload_target_srl = $upload_target_srl;
  619. $args->module_srl = $module_srl;
  620. $args->direct_download = $direct_download;
  621. $args->source_filename = $file_info['name'];
  622. $args->uploaded_filename = $filename;
  623. $args->download_count = $download_count;
  624. $args->file_size = @filesize($filename);
  625. $args->comment = NULL;
  626. $args->member_srl = $member_srl;
  627. $args->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999)));
  628. $output = executeQuery('file.insertFile', $args);
  629. if(!$output->toBool()) return $output;
  630. // Call a trigger (after)
  631. $trigger_output = ModuleHandler::triggerCall('file.insertFile', 'after', $args);
  632. if(!$trigger_output->toBool()) return $trigger_output;
  633. $_SESSION['__XE_UPLOADING_FILES_INFO__'][$args->file_srl] = true;
  634. $output->add('file_srl', $args->file_srl);
  635. $output->add('file_size', $args->file_size);
  636. $output->add('sid', $args->sid);
  637. $output->add('direct_download', $args->direct_download);
  638. $output->add('source_filename', $args->source_filename);
  639. $output->add('upload_target_srl', $upload_target_srl);
  640. $output->add('uploaded_filename', $args->uploaded_filename);
  641. return $output;
  642. }
  643. /**
  644. * Delete the attachment
  645. *
  646. * <pre>
  647. * This method call trigger 'file.deleteFile'.
  648. * Before, after trigger object contains:
  649. * - download_url
  650. * - file_srl
  651. * - upload_target_srl
  652. * - upload_target_type
  653. * - sid
  654. * - module_srl
  655. * - member_srl
  656. * - download_count
  657. * - direct_download
  658. * - source_filename
  659. * - uploaded_filename
  660. * - file_size
  661. * - comment
  662. * - isvalid
  663. * - regdate
  664. * - ipaddress
  665. * </pre>
  666. *
  667. * @param int $file_srl Sequence of file to delete
  668. * @return Object
  669. */
  670. function deleteFile($file_srl)
  671. {
  672. if(!$file_srl) return;
  673. $srls = explode(',',$file_srl);
  674. if(!count($srls)) return;
  675. $oDocumentController = getController('document');
  676. $documentSrlList = array();
  677. for($i=0;$i<count($srls);$i++)
  678. {
  679. $srl = (int)$srls[$i];
  680. if(!$srl) continue;
  681. $args = new stdClass;
  682. $args->file_srl = $srl;
  683. $output = executeQuery('file.getFile', $args);
  684. if(!$output->toBool()) continue;
  685. $file_info = $output->data;
  686. if(!$file_info) continue;
  687. if($file_info->upload_target_srl)
  688. {
  689. $documentSrlList[] = $file_info->upload_target_srl;
  690. }
  691. $source_filename = $output->data->source_filename;
  692. $uploaded_filename = $output->data->uploaded_filename;
  693. // Call a trigger (before)
  694. $trigger_obj = $output->data;
  695. $output = ModuleHandler::triggerCall('file.deleteFile', 'before', $trigger_obj);
  696. if(!$output->toBool()) return $output;
  697. // Remove from the DB
  698. $output = executeQuery('file.deleteFile', $args);
  699. if(!$output->toBool()) return $output;
  700. // Call a trigger (after)
  701. $trigger_output = ModuleHandler::triggerCall('file.deleteFile', 'after', $trigger_obj);
  702. if(!$trigger_output->toBool()) return $trigger_output;
  703. // If successfully deleted, remove the file
  704. FileHandler::removeFile($uploaded_filename);
  705. }
  706. $oDocumentController->updateUploaedCount($documentSrlList);
  707. return $output;
  708. }
  709. /**
  710. * Delete all attachments of a particular document
  711. *
  712. * @param int $upload_target_srl Upload target srl to delete files
  713. * @return Object
  714. */
  715. function deleteFiles($upload_target_srl)
  716. {
  717. // Get a list of attachements
  718. $oFileModel = getModel('file');
  719. $columnList = array('uploaded_filename', 'module_srl');
  720. $file_list = $oFileModel->getFiles($upload_target_srl, $columnList);
  721. // Success returned if no attachement exists
  722. if(!is_array($file_list)||!count($file_list)) return new Object();
  723. // Remove from the DB
  724. $args = new stdClass();
  725. $args->upload_target_srl = $upload_target_srl;
  726. $output = executeQuery('file.deleteFiles', $args);
  727. if(!$output->toBool()) return $output;
  728. // Delete the file
  729. $path = array();
  730. $file_count = count($file_list);
  731. for($i=0;$i<$file_count;$i++)
  732. {
  733. $uploaded_filename = $file_list[$i]->uploaded_filename;
  734. FileHandler::removeFile($uploaded_filename);
  735. $module_srl = $file_list[$i]->module_srl;
  736. $path_info = pathinfo($uploaded_filename);
  737. if(!in_array($path_info['dirname'], $path)) $path[] = $path_info['dirname'];
  738. }
  739. // Remove a file directory of the document
  740. for($i=0;$i<count($path);$i++) FileHandler::removeBlankDir($path[$i]);
  741. return $output;
  742. }
  743. /**
  744. * Move an attachement to the other document
  745. *
  746. * @param int $source_srl Sequence of target to move
  747. * @param int $target_module_srl New squence of module
  748. * @param int $target_srl New sequence of target
  749. * @return void
  750. */
  751. function moveFile($source_srl, $target_module_srl, $target_srl)
  752. {
  753. if($source_srl == $target_srl) return;
  754. $oFileModel = getModel('file');
  755. $file_list = $oFileModel->getFiles($source_srl);
  756. if(!$file_list) return;
  757. $file_count = count($file_list);
  758. for($i=0;$i<$file_count;$i++)
  759. {
  760. unset($file_info);
  761. $file_info = $file_list[$i];
  762. $old_file = $file_info->uploaded_filename;
  763. // Determine the file path by checking if the file is an image or other kinds
  764. if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_info->source_filename))
  765. {
  766. $path = sprintf("./files/attach/images/%s/%s/", $target_module_srl,$target_srl);
  767. $new_file = $path.$file_info->source_filename;
  768. }
  769. else
  770. {
  771. $path = sprintf("./files/attach/binaries/%s/%s/", $target_module_srl, $target_srl);
  772. $new_file = $path.md5(crypt(rand(1000000,900000), rand(0,100)));
  773. }
  774. // Pass if a target document to move is same
  775. if($old_file == $new_file) continue;
  776. // Create a directory
  777. FileHandler::makeDir($path);
  778. // Move the file
  779. FileHandler::rename($old_file, $new_file);
  780. // Update DB information
  781. $args = new stdClass;
  782. $args->file_srl = $file_info->file_srl;
  783. $args->uploaded_filename = $new_file;
  784. $args->module_srl = $file_info->module_srl;
  785. $args->upload_target_srl = $target_srl;
  786. executeQuery('file.updateFile', $args);
  787. }
  788. }
  789. /**
  790. * Find the attachment where a key is upload_target_srl and then return java script code
  791. *
  792. * @deprecated
  793. * @param int $editor_sequence
  794. * @param int $upload_target_srl
  795. * @return void
  796. */
  797. function printUploadedFileList($editor_sequence, $upload_target_srl)
  798. {
  799. return;
  800. }
  801. function triggerCopyModule(&$obj)
  802. {
  803. $oModuleModel = getModel('module');
  804. $fileConfig = $oModuleModel->getModulePartConfig('file', $obj->originModuleSrl);
  805. $oModuleController = getController('module');
  806. if(is_array($obj->moduleSrlList))
  807. {
  808. foreach($obj->moduleSrlList AS $key=>$moduleSrl)
  809. {
  810. $oModuleController->insertModulePartConfig('file', $moduleSrl, $fileConfig);
  811. }
  812. }
  813. }
  814. }
  815. /* End of file file.controller.php */
  816. /* Location: ./modules/file/file.controller.php */