@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 120 lines 3.3 kB view raw
1<?php 2 3final class PhabricatorFileDropUploadController 4 extends PhabricatorFileController { 5 6 public function shouldAllowRestrictedParameter($parameter_name) { 7 // Prevent false positives from file content when it is submitted via 8 // drag-and-drop upload. 9 return true; 10 } 11 12 /** 13 * @phutil-external-symbol class PhabricatorStartup 14 */ 15 public function handleRequest(AphrontRequest $request) { 16 $viewer = $request->getViewer(); 17 18 // NOTE: Throws if valid CSRF token is not present in the request. 19 $request->validateCSRF(); 20 21 $name = $request->getStr('name'); 22 $file_phid = $request->getStr('phid'); 23 // If there's no explicit view policy, make it very restrictive by default. 24 // This is the correct policy for files dropped onto objects during 25 // creation, comment and edit flows. 26 $view_policy = $request->getStr('viewPolicy'); 27 if (!$view_policy) { 28 $view_policy = $viewer->getPHID(); 29 } 30 31 $is_chunks = $request->getBool('querychunks'); 32 if ($is_chunks) { 33 $params = array( 34 'filePHID' => $file_phid, 35 ); 36 37 $result = id(new ConduitCall('file.querychunks', $params)) 38 ->setUser($viewer) 39 ->execute(); 40 41 return id(new AphrontAjaxResponse())->setContent($result); 42 } 43 44 $is_allocate = $request->getBool('allocate'); 45 if ($is_allocate) { 46 $params = array( 47 'name' => $name, 48 'contentLength' => $request->getInt('length'), 49 'viewPolicy' => $view_policy, 50 ); 51 52 $result = id(new ConduitCall('file.allocate', $params)) 53 ->setUser($viewer) 54 ->execute(); 55 56 $file_phid = $result['filePHID']; 57 if ($file_phid) { 58 $file = $this->loadFile($file_phid); 59 $result += $file->getDragAndDropDictionary(); 60 } 61 62 return id(new AphrontAjaxResponse())->setContent($result); 63 } 64 65 // Read the raw request data. We're either doing a chunk upload or a 66 // vanilla upload, so we need it. 67 $data = PhabricatorStartup::getRawInput(); 68 69 $is_chunk_upload = $request->getBool('uploadchunk'); 70 if ($is_chunk_upload) { 71 $params = array( 72 'filePHID' => $file_phid, 73 'byteStart' => $request->getInt('byteStart'), 74 'data' => $data, 75 ); 76 77 $result = id(new ConduitCall('file.uploadchunk', $params)) 78 ->setUser($viewer) 79 ->execute(); 80 81 $file = $this->loadFile($file_phid); 82 if ($file->getIsPartial()) { 83 $result = array(); 84 } else { 85 $result = array( 86 'complete' => true, 87 ) + $file->getDragAndDropDictionary(); 88 } 89 90 return id(new AphrontAjaxResponse())->setContent($result); 91 } 92 93 $file = PhabricatorFile::newFromXHRUpload( 94 $data, 95 array( 96 'name' => $request->getStr('name'), 97 'authorPHID' => $viewer->getPHID(), 98 'viewPolicy' => $view_policy, 99 'isExplicitUpload' => true, 100 )); 101 102 $result = $file->getDragAndDropDictionary(); 103 return id(new AphrontAjaxResponse())->setContent($result); 104 } 105 106 private function loadFile($file_phid) { 107 $viewer = $this->getViewer(); 108 109 $file = id(new PhabricatorFileQuery()) 110 ->setViewer($viewer) 111 ->withPHIDs(array($file_phid)) 112 ->executeOne(); 113 if (!$file) { 114 throw new Exception(pht('Failed to load file.')); 115 } 116 117 return $file; 118 } 119 120}