Differential D12066 Diff 29041 src/applications/files/controller/PhabricatorFileDropUploadController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/files/controller/PhabricatorFileDropUploadController.php
<?php | <?php | ||||
final class PhabricatorFileDropUploadController | final class PhabricatorFileDropUploadController | ||||
extends PhabricatorFileController { | extends PhabricatorFileController { | ||||
/** | /** | ||||
* @phutil-external-symbol class PhabricatorStartup | * @phutil-external-symbol class PhabricatorStartup | ||||
*/ | */ | ||||
public function processRequest() { | public function processRequest() { | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
// NOTE: Throws if valid CSRF token is not present in the request. | // NOTE: Throws if valid CSRF token is not present in the request. | ||||
$request->validateCSRF(); | $request->validateCSRF(); | ||||
$data = PhabricatorStartup::getRawInput(); | |||||
$name = $request->getStr('name'); | $name = $request->getStr('name'); | ||||
$file_phid = $request->getStr('phid'); | |||||
// If there's no explicit view policy, make it very restrictive by default. | // If there's no explicit view policy, make it very restrictive by default. | ||||
// This is the correct policy for files dropped onto objects during | // This is the correct policy for files dropped onto objects during | ||||
// creation, comment and edit flows. | // creation, comment and edit flows. | ||||
$view_policy = $request->getStr('viewPolicy'); | $view_policy = $request->getStr('viewPolicy'); | ||||
if (!$view_policy) { | if (!$view_policy) { | ||||
$view_policy = $viewer->getPHID(); | $view_policy = $viewer->getPHID(); | ||||
} | } | ||||
$is_chunks = $request->getBool('querychunks'); | |||||
if ($is_chunks) { | |||||
$params = array( | |||||
'filePHID' => $file_phid, | |||||
); | |||||
$result = id(new ConduitCall('file.querychunks', $params)) | |||||
->setUser($viewer) | |||||
->execute(); | |||||
return id(new AphrontAjaxResponse())->setContent($result); | |||||
} | |||||
$is_allocate = $request->getBool('allocate'); | |||||
if ($is_allocate) { | |||||
$params = array( | |||||
'name' => $name, | |||||
'contentLength' => $request->getInt('length'), | |||||
'viewPolicy' => $view_policy, | |||||
// TODO: Remove. | |||||
// 'forceChunking' => true, | |||||
); | |||||
$result = id(new ConduitCall('file.allocate', $params)) | |||||
->setUser($viewer) | |||||
->execute(); | |||||
$file_phid = $result['filePHID']; | |||||
if ($file_phid) { | |||||
$file = $this->loadFile($file_phid); | |||||
$result += $this->getFileDictionary($file); | |||||
} | |||||
return id(new AphrontAjaxResponse())->setContent($result); | |||||
} | |||||
// Read the raw request data. We're either doing a chunk upload or a | |||||
// vanilla upload, so we need it. | |||||
$data = PhabricatorStartup::getRawInput(); | |||||
$is_chunk_upload = $request->getBool('uploadchunk'); | |||||
if ($is_chunk_upload) { | |||||
$params = array( | |||||
'filePHID' => $file_phid, | |||||
'byteStart' => $request->getInt('byteStart'), | |||||
'data' => $data, | |||||
); | |||||
$result = id(new ConduitCall('file.uploadchunk', $params)) | |||||
->setUser($viewer) | |||||
->execute(); | |||||
$file = $this->loadFile($file_phid); | |||||
if ($file->getIsPartial()) { | |||||
$result = array(); | |||||
} else { | |||||
$result = array( | |||||
'complete' => true, | |||||
) + $this->getFileDictionary($file); | |||||
} | |||||
return id(new AphrontAjaxResponse())->setContent($result); | |||||
} | |||||
$file = PhabricatorFile::newFromXHRUpload( | $file = PhabricatorFile::newFromXHRUpload( | ||||
$data, | $data, | ||||
array( | array( | ||||
'name' => $request->getStr('name'), | 'name' => $request->getStr('name'), | ||||
'authorPHID' => $viewer->getPHID(), | 'authorPHID' => $viewer->getPHID(), | ||||
'viewPolicy' => $view_policy, | 'viewPolicy' => $view_policy, | ||||
'isExplicitUpload' => true, | 'isExplicitUpload' => true, | ||||
)); | )); | ||||
return id(new AphrontAjaxResponse())->setContent( | $result = $this->getFileDictionary($file); | ||||
array( | return id(new AphrontAjaxResponse())->setContent($result); | ||||
} | |||||
private function getFileDictionary(PhabricatorFile $file) { | |||||
return array( | |||||
'id' => $file->getID(), | 'id' => $file->getID(), | ||||
'phid' => $file->getPHID(), | 'phid' => $file->getPHID(), | ||||
'uri' => $file->getBestURI(), | 'uri' => $file->getBestURI(), | ||||
)); | ); | ||||
} | |||||
private function loadFile($file_phid) { | |||||
$viewer = $this->getViewer(); | |||||
$file = id(new PhabricatorFileQuery()) | |||||
->setViewer($viewer) | |||||
->withPHIDs(array($file_phid)) | |||||
->executeOne(); | |||||
if (!$file) { | |||||
throw new Exception(pht('Failed to load file.')); | |||||
} | |||||
return $file; | |||||
} | } | ||||
} | } |