diff --git a/src/Console/ListGroupDirectoryCommand.php b/src/Console/ListGroupDirectoryCommand.php index 6f0a79e..626ffaf 100644 --- a/src/Console/ListGroupDirectoryCommand.php +++ b/src/Console/ListGroupDirectoryCommand.php @@ -22,7 +22,6 @@ class ListGroupDirectoryCommand extends Command */ protected $description = 'List and create the directories for the groups'; - protected $resourceHandler; /** * Create a new command instance. diff --git a/src/RedisSavedPath.php b/src/RedisSavedPath.php index 0412ef9..2316fa0 100644 --- a/src/RedisSavedPath.php +++ b/src/RedisSavedPath.php @@ -8,12 +8,12 @@ class RedisSavedPath { /** - * @param $resourceHash + * @param $key * @return bool */ - public static function exists($resourceHash) + public static function exists($key) { - $result = Redis::hexists('aetherupload_resource', $resourceHash); + $result = Redis::hexists('aetherupload_resource', $key); if ( $result !== 1 && $result !== 0 ) { throw new \Exception('exists error'); @@ -23,12 +23,12 @@ public static function exists($resourceHash) } /** - * @param $resourceHash + * @param $key * @return string */ - public static function get($resourceHash) + public static function get($key) { - $result = Redis::hget('aetherupload_resource', $resourceHash); + $result = Redis::hget('aetherupload_resource', $key); if ( $result === null) { throw new \Exception('read error'); @@ -39,13 +39,13 @@ public static function get($resourceHash) /** * set or overwrite a hash - * @param $resourceHash + * @param $key * @param $savedPath * @return bool */ - public static function set($savedPathKey, $savedPath) + public static function set($key, $savedPath) { - $result = Redis::hset('aetherupload_resource', $savedPathKey, $savedPath); + $result = Redis::hset('aetherupload_resource', $key, $savedPath); if ( $result !== 0 && $result !== 1 ) { throw new \Exception('write error'); @@ -55,23 +55,23 @@ public static function set($savedPathKey, $savedPath) } /** - * @param $resourceHashArr + * @param $keyArr * @return bool */ - public static function setMulti($resourceHashArr) + public static function setMulti($keyArr) { - $result = Redis::hmset('aetherupload_resource', $resourceHashArr); + $result = Redis::hmset('aetherupload_resource', $keyArr); return $result; } /** - * @param $resourceHash + * @param $key * @return bool */ - public static function delete($resourceHash) + public static function delete($key) { - $result = Redis::hdel('aetherupload_resource', $resourceHash); + $result = Redis::hdel('aetherupload_resource', $key); if ( $result !== 1 ) { throw new \Exception('delete error'); @@ -88,4 +88,4 @@ public static function deleteAll() } -} \ No newline at end of file +} diff --git a/src/Resource.php b/src/Resource.php index 4b19e80..db62b16 100644 --- a/src/Resource.php +++ b/src/Resource.php @@ -14,11 +14,11 @@ class Resource public $path; public $realPath; - public function __construct($name, $groupSubDir) + public function __construct($group, $groupSubDir, $name) { $this->disk = Storage::disk('local'); $this->name = $name; - $this->group = ConfigMapper::get('group'); + $this->group = $group; $this->groupDir = ConfigMapper::get('group_dir'); $this->groupSubDir = $groupSubDir; $this->path = $this->getPath(); diff --git a/src/ResourceController.php b/src/ResourceController.php index bebb1eb..5b89bf4 100644 --- a/src/ResourceController.php +++ b/src/ResourceController.php @@ -17,7 +17,7 @@ public function display($uri) ConfigMapper::instance()->applyGroupConfig($group); - $resource = new Resource($resourceName, $groupSubDir); + $resource = new Resource($group, $groupSubDir, $resourceName); if ( $resource->exists($resource->path) === false ) { throw new \Exception; @@ -41,7 +41,7 @@ public function download($uri, $newName = null) ConfigMapper::instance()->applyGroupConfig($group); - $resource = new Resource($resourceName, $groupSubDir); + $resource = new Resource($group, $groupSubDir ,$resourceName); if ( $resource->exists($resource->path) === false ) { throw new \Exception; @@ -58,4 +58,4 @@ public function download($uri, $newName = null) } -} \ No newline at end of file +} diff --git a/src/UploadController.php b/src/UploadController.php index a38c1c2..7c0db1b 100644 --- a/src/UploadController.php +++ b/src/UploadController.php @@ -1,204 +1,204 @@ -middleware(ConfigMapper::get('distributed_deployment_middleware_cors')); - } - } - - /** - * Preprocess the upload request - * @return \Illuminate\Http\JsonResponse - */ - public function preprocess() - { - $resourceName = Request::input('resource_name', false); - $resourceSize = Request::input('resource_size', false); - $resourceHash = Request::input('resource_hash', false); - $group = Request::input('group', false); - - $result = [ - 'error' => 0, - 'chunkSize' => 0, - 'groupSubDir' => '', - 'resourceTempBaseName' => '', - 'resourceExt' => '', - 'savedPath' => '', - ]; - - try { - - // prevents uploading files to the application server when distributed deployment is enabled - if ( Util::isDistributedWebHost() ) { - throw new \Exception(trans('aetherupload::messages.upload_error')); - } - - if ( $resourceSize === false || $resourceName === false || $group === false ) { - throw new \Exception(trans('aetherupload::messages.invalid_resource_params')); - } - - ConfigMapper::instance()->applyGroupConfig($group); - - $result['resourceTempBaseName'] = $resourceTempBaseName = Util::generateTempName(); - $result['resourceExt'] = $resourceExt = strtolower(pathinfo($resourceName, PATHINFO_EXTENSION)); - $result['groupSubDir'] = $groupSubDir = Util::generateSubDirName(); - $result['chunkSize'] = ConfigMapper::get('chunk_size'); - - $partialResource = new PartialResource($resourceTempBaseName, $resourceExt, $groupSubDir); - - $partialResource->filterBySize($resourceSize); - - $partialResource->filterByExtension($resourceExt); - - // determine if this upload meets the condition of instant completion - if ( $resourceHash !== false && ConfigMapper::get('instant_completion') === true && RedisSavedPath::exists($savedPathKey = Util::getSavedPathKey($group, $resourceHash)) ) { - $result['savedPath'] = RedisSavedPath::get($savedPathKey); - - return Responser::returnResult($result); - } - - $partialResource->create(); - - $partialResource->chunkIndex = 0; - - } catch ( \Exception $e ) { - - return Responser::reportError($result, $e->getMessage()); - } - - return Responser::returnResult($result); - } - - /** - * Handle and save the uploaded chunks - * @return \Illuminate\Http\JsonResponse - * @throws \Exception - */ - public function saveChunk() - { - $chunkTotalCount = Request::input('chunk_total', false); - $chunkIndex = Request::input('chunk_index', false); - $resourceTempBaseName = Request::input('resource_temp_basename', false); - $resourceExt = Request::input('resource_ext', false); - $chunk = Request::file('resource_chunk', false); - $groupSubDir = Request::input('group_subdir', false); - $resourceHash = Request::input('resource_hash', false); - $group = Request::input('group', false); - $savedPathKey = Util::getSavedPathKey($group, $resourceHash); - $partialResource = null; - - $result = [ - 'error' => 0, - 'savedPath' => '', - ]; - - try { - - if ( $chunkTotalCount === false || $chunkIndex === false || $resourceExt === false || $resourceTempBaseName === false || $groupSubDir === false || $chunk === false || $resourceHash === false || $group === false ) { - throw new \Exception(trans('aetherupload::messages.invalid_chunk_params')); - } - - ConfigMapper::instance()->applyGroupConfig($group); - - $partialResource = new PartialResource($resourceTempBaseName, $resourceExt, $groupSubDir); - - // do a check to prevent security intrusions - if ( $partialResource->exists() === false ) { - throw new \Exception(trans('aetherupload::messages.invalid_operation')); - } - - // determine if this upload meets the condition of instant completion - if ( $resourceHash !== false && ConfigMapper::get('instant_completion') === true && RedisSavedPath::exists($savedPathKey) ) { - $partialResource->delete(); - unset($partialResource->chunkIndex); - $result['savedPath'] = RedisSavedPath::get($savedPathKey); - - return Responser::returnResult($result); - } - - if ( $chunk->getError() > 0 ) { - throw new \Exception(trans('aetherupload::messages.upload_error')); - } - - if ( $chunk->isValid() === false ) { - throw new \Exception(trans('aetherupload::messages.http_post_only')); - } - - // validate the data in header file to avoid the errors when network issue occurs - if ( (int)($partialResource->chunkIndex) !== (int)$chunkIndex - 1 ) { - return Responser::returnResult($result); - } - - $partialResource->append($chunk->getRealPath()); - - $partialResource->chunkIndex = $chunkIndex; - - // determine if the resource file is completed - if ( $chunkIndex === $chunkTotalCount ) { - - $partialResource->checkSize(); - - $partialResource->checkMimeType(); - - // trigger the event before an upload completes - if ( empty($beforeUploadCompleteEvent = ConfigMapper::get('event_before_upload_complete')) === false ) { - event(new $beforeUploadCompleteEvent($partialResource)); - } - - $resourceHash = $partialResource->calculateHash(); - - $partialResource->rename($completeName = Util::getFileName($resourceHash, $resourceExt)); - - $resource = new Resource($completeName, $groupSubDir); - - $savedPath = $resource->getSavedPath(); - - if ( ConfigMapper::get('instant_completion') === true ) { - RedisSavedPath::set($savedPathKey, $savedPath); - } - - unset($partialResource->chunkIndex); - - // trigger the event when an upload completes - if ( empty($uploadCompleteEvent = ConfigMapper::get('event_upload_complete')) === false ) { - event(new $uploadCompleteEvent($resource)); - } - - $result['savedPath'] = $savedPath; - - } - - return Responser::returnResult($result); - - } catch ( \Exception $e ) { - - $partialResource->delete(); - unset($partialResource->chunkIndex); - - return Responser::reportError($result, $e->getMessage()); - } - - } - - /** - * Handle the request of option method in CORS - * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response - */ - public function options() - { - return response(''); - } - - -} \ No newline at end of file +middleware(ConfigMapper::get('distributed_deployment_middleware_cors')); + } + } + + /** + * Preprocess the upload request + * @return \Illuminate\Http\JsonResponse + */ + public function preprocess() + { + $resourceName = Request::input('resource_name', false); + $resourceSize = Request::input('resource_size', false); + $resourceHash = Request::input('resource_hash', false); + $group = Request::input('group', false); + + $result = [ + 'error' => 0, + 'chunkSize' => 0, + 'groupSubDir' => '', + 'resourceTempBaseName' => '', + 'resourceExt' => '', + 'savedPath' => '', + ]; + + try { + + // prevents uploading files to the application server when distributed deployment is enabled + if ( Util::isDistributedWebHost() ) { + throw new \Exception(trans('aetherupload::messages.upload_error')); + } + + if ( $resourceSize === false || $resourceName === false || $group === false ) { + throw new \Exception(trans('aetherupload::messages.invalid_resource_params')); + } + + ConfigMapper::instance()->applyGroupConfig($group); + + $result['resourceTempBaseName'] = $resourceTempBaseName = Util::generateTempName(); + $result['resourceExt'] = $resourceExt = strtolower(pathinfo($resourceName, PATHINFO_EXTENSION)); + $result['groupSubDir'] = $groupSubDir = Util::generateSubDirName(); + $result['chunkSize'] = ConfigMapper::get('chunk_size'); + + $partialResource = new PartialResource($resourceTempBaseName, $resourceExt, $groupSubDir); + + $partialResource->filterBySize($resourceSize); + + $partialResource->filterByExtension($resourceExt); + + // determine if this upload meets the condition of instant completion + if ( $resourceHash !== false && ConfigMapper::get('instant_completion') === true && RedisSavedPath::exists($savedPathKey = Util::getSavedPathKey($group, $resourceHash)) ) { + $result['savedPath'] = RedisSavedPath::get($savedPathKey); + + return Responser::returnResult($result); + } + + $partialResource->create(); + + $partialResource->chunkIndex = 0; + + } catch ( \Exception $e ) { + + return Responser::reportError($result, $e->getMessage()); + } + + return Responser::returnResult($result); + } + + /** + * Handle and save the uploaded chunks + * @return \Illuminate\Http\JsonResponse + * @throws \Exception + */ + public function saveChunk() + { + $chunkTotalCount = Request::input('chunk_total', false); + $chunkIndex = Request::input('chunk_index', false); + $resourceTempBaseName = Request::input('resource_temp_basename', false); + $resourceExt = Request::input('resource_ext', false); + $chunk = Request::file('resource_chunk', false); + $groupSubDir = Request::input('group_subdir', false); + $resourceHash = Request::input('resource_hash', false); + $group = Request::input('group', false); + $savedPathKey = Util::getSavedPathKey($group, $resourceHash); + $partialResource = null; + + $result = [ + 'error' => 0, + 'savedPath' => '', + ]; + + try { + + if ( $chunkTotalCount === false || $chunkIndex === false || $resourceExt === false || $resourceTempBaseName === false || $groupSubDir === false || $chunk === false || $resourceHash === false || $group === false ) { + throw new \Exception(trans('aetherupload::messages.invalid_chunk_params')); + } + + ConfigMapper::instance()->applyGroupConfig($group); + + $partialResource = new PartialResource($resourceTempBaseName, $resourceExt, $groupSubDir); + + // do a check to prevent security intrusions + if ( $partialResource->exists() === false ) { + throw new \Exception(trans('aetherupload::messages.invalid_operation')); + } + + // determine if this upload meets the condition of instant completion + if ( $resourceHash !== false && ConfigMapper::get('instant_completion') === true && RedisSavedPath::exists($savedPathKey) ) { + $partialResource->delete(); + unset($partialResource->chunkIndex); + $result['savedPath'] = RedisSavedPath::get($savedPathKey); + + return Responser::returnResult($result); + } + + if ( $chunk->getError() > 0 ) { + throw new \Exception(trans('aetherupload::messages.upload_error')); + } + + if ( $chunk->isValid() === false ) { + throw new \Exception(trans('aetherupload::messages.http_post_only')); + } + + // validate the data in header file to avoid the errors when network issue occurs + if ( (int)($partialResource->chunkIndex) !== (int)$chunkIndex - 1 ) { + return Responser::returnResult($result); + } + + $partialResource->append($chunk->getRealPath()); + + $partialResource->chunkIndex = $chunkIndex; + + // determine if the resource file is completed + if ( $chunkIndex === $chunkTotalCount ) { + + $partialResource->checkSize(); + + $partialResource->checkMimeType(); + + // trigger the event before an upload completes + if ( empty($beforeUploadCompleteEvent = ConfigMapper::get('event_before_upload_complete')) === false ) { + event(new $beforeUploadCompleteEvent($partialResource)); + } + + $resourceHash = $partialResource->calculateHash(); + + $partialResource->rename($completeName = Util::getFileName($resourceHash, $resourceExt)); + + $resource = new Resource($group, $groupSubDir, $completeName); + + $savedPath = $resource->getSavedPath(); + + if ( ConfigMapper::get('instant_completion') === true ) { + RedisSavedPath::set($savedPathKey, $savedPath); + } + + unset($partialResource->chunkIndex); + + // trigger the event when an upload completes + if ( empty($uploadCompleteEvent = ConfigMapper::get('event_upload_complete')) === false ) { + event(new $uploadCompleteEvent($resource)); + } + + $result['savedPath'] = $savedPath; + + } + + return Responser::returnResult($result); + + } catch ( \Exception $e ) { + + $partialResource->delete(); + unset($partialResource->chunkIndex); + + return Responser::reportError($result, $e->getMessage()); + } + + } + + /** + * Handle the request of option method in CORS + * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response + */ + public function options() + { + return response(''); + } + + +}