Path: blob/master/src/applications/files/conduit/FileAllocateConduitAPIMethod.php
12241 views
<?php12final class FileAllocateConduitAPIMethod3extends FileConduitAPIMethod {45public function getAPIMethodName() {6return 'file.allocate';7}89public function getMethodDescription() {10return pht('Prepare to upload a file.');11}1213protected function defineParamTypes() {14return array(15'name' => 'string',16'contentLength' => 'int',17'contentHash' => 'optional string',18'viewPolicy' => 'optional string',19'deleteAfterEpoch' => 'optional int',20);21}2223protected function defineReturnType() {24return 'map<string, wild>';25}2627protected function execute(ConduitAPIRequest $request) {28$viewer = $request->getUser();2930$hash = $request->getValue('contentHash');31$name = $request->getValue('name');32$view_policy = $request->getValue('viewPolicy');33$length = $request->getValue('contentLength');3435$properties = array(36'name' => $name,37'authorPHID' => $viewer->getPHID(),38'isExplicitUpload' => true,39);4041if ($view_policy !== null) {42$properties['viewPolicy'] = $view_policy;43}4445$ttl = $request->getValue('deleteAfterEpoch');46if ($ttl) {47$properties['ttl.absolute'] = $ttl;48}4950$file = null;51if ($hash !== null) {52$file = PhabricatorFile::newFileFromContentHash(53$hash,54$properties);55}5657if ($hash !== null && !$file) {58$chunked_hash = PhabricatorChunkedFileStorageEngine::getChunkedHash(59$viewer,60$hash);61$file = id(new PhabricatorFileQuery())62->setViewer($viewer)63->withContentHashes(array($chunked_hash))64->executeOne();65}6667if ($name !== null && strlen($name) && !$hash && !$file) {68if ($length > PhabricatorFileStorageEngine::getChunkThreshold()) {69// If we don't have a hash, but this file is large enough to store in70// chunks and thus may be resumable, try to find a partially uploaded71// file by the same author with the same name and same length. This72// allows us to resume uploads in Javascript where we can't efficiently73// compute file hashes.74$file = id(new PhabricatorFileQuery())75->setViewer($viewer)76->withAuthorPHIDs(array($viewer->getPHID()))77->withNames(array($name))78->withLengthBetween($length, $length)79->withIsPartial(true)80->setLimit(1)81->executeOne();82}83}8485if ($file) {86return array(87'upload' => (bool)$file->getIsPartial(),88'filePHID' => $file->getPHID(),89);90}9192// If there are any non-chunk engines which this file can fit into,93// just tell the client to upload the file.94$engines = PhabricatorFileStorageEngine::loadStorageEngines($length);95if ($engines) {96return array(97'upload' => true,98'filePHID' => null,99);100}101102// Otherwise, this is a large file and we want to perform a chunked103// upload if we have a chunk engine available.104$chunk_engines = PhabricatorFileStorageEngine::loadWritableChunkEngines();105if ($chunk_engines) {106$chunk_properties = $properties;107108if ($hash !== null) {109$chunk_properties += array(110'chunkedHash' => $chunked_hash,111);112}113114$chunk_engine = head($chunk_engines);115$file = $chunk_engine->allocateChunks($length, $chunk_properties);116117return array(118'upload' => true,119'filePHID' => $file->getPHID(),120);121}122123// None of the storage engines can accept this file.124if (PhabricatorFileStorageEngine::loadWritableEngines()) {125$error = pht(126'Unable to upload file: this file is too large for any '.127'configured storage engine.');128} else {129$error = pht(130'Unable to upload file: the server is not configured with any '.131'writable storage engines.');132}133134return array(135'upload' => false,136'filePHID' => null,137'error' => $error,138);139}140141}142143144