|
@@ -0,0 +1,115 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services\File;
|
|
|
+
|
|
|
+use App\Http\Resources\API\FileDownloadResource;
|
|
|
+use App\Models\Enums\FileObjectType;
|
|
|
+use App\Models\Enums\FolderObjectType;
|
|
|
+use App\Models\File;
|
|
|
+use App\Models\Folder;
|
|
|
+use Illuminate\Support\Collection;
|
|
|
+
|
|
|
+class DownloadService
|
|
|
+{
|
|
|
+ public function downloadByIds(array $ids)
|
|
|
+ {
|
|
|
+ $files = File::query()->with(['folder'])->whereIn("id", $ids)->get();
|
|
|
+
|
|
|
+ return $this->filesFormat($files);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function downloadAllLatest(string $objectType, string $objectId)
|
|
|
+ {
|
|
|
+ $folderObjectType = FolderObjectType::from($objectType);
|
|
|
+
|
|
|
+ $object = $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
|
|
|
+
|
|
|
+ $isExternalVersionControl = $this->isExternalVersionControl($folderObjectType);
|
|
|
+
|
|
|
+ $fileIds = $isExternalVersionControl ? $this->versionFileIds($folderObjectType, $object) : [];
|
|
|
+
|
|
|
+ $files = File::query()->with(['folder'])->where([
|
|
|
+ 'object_type' => $objectType,
|
|
|
+ 'object_id' => $objectId,
|
|
|
+ ])->when(! $isExternalVersionControl, fn($query) => $query->where("is_latest_version", 1))
|
|
|
+ ->when($fileIds, fn($query) => $query->whereIn("id", $fileIds))
|
|
|
+ ->orderByDesc("version")
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ $files = $isExternalVersionControl ? $this->getLatestFiles($files, $object) : $files;
|
|
|
+
|
|
|
+ return $this->filesFormat($files);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function isExternalVersionControl(FolderObjectType $folderObjectType)
|
|
|
+ {
|
|
|
+ return $folderObjectType == FolderObjectType::CONTAINER && request("object_version", 0) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function getLatestFiles(Collection $files, $object)
|
|
|
+ {
|
|
|
+ $objectVersion = request('object_version') ?: $object->version;
|
|
|
+
|
|
|
+ $items = [];
|
|
|
+
|
|
|
+ foreach ($files->groupBy("folder_id") as $folderFiles) {
|
|
|
+ foreach ($folderFiles as $file) {
|
|
|
+ $isHide = $file->hide_object_version == 0
|
|
|
+ ? (bool)$file->is_hide
|
|
|
+ : $file->is_hide && $file->hide_object_version <= $objectVersion;
|
|
|
+ if (! $isHide) {
|
|
|
+ $items[] = $file;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return collect($items);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function versionFileIds(FolderObjectType $folderObjectType, $object)
|
|
|
+ {
|
|
|
+ $fileIds = [];
|
|
|
+ if ($folderObjectType == FolderObjectType::CONTAINER) {
|
|
|
+ $containerContent = $object->content(request('object_version') ?: $object->version)->first();
|
|
|
+
|
|
|
+ throw_validation_if(! $containerContent, "The current version does not exist");
|
|
|
+
|
|
|
+ $fileIds = explode(",", $containerContent->files);
|
|
|
+ }
|
|
|
+
|
|
|
+ return array_unique(array_filter($fileIds));
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function filesFormat(Collection $files)
|
|
|
+ {
|
|
|
+ $folderIds = [];
|
|
|
+ foreach ($files as $file) {
|
|
|
+ $folderIds = [...$folderIds, ...explode(",", $file->folder?->path)];
|
|
|
+ }
|
|
|
+
|
|
|
+ $folders = Folder::query()->whereIn("id", array_unique(array_filter($folderIds)))->pluck("name", "id");
|
|
|
+
|
|
|
+ $items = [];
|
|
|
+ foreach ($files as $file) {
|
|
|
+ $object = FileObjectType::from($file->object_type)
|
|
|
+ ->modelBuilderAllowed($file->object_id)
|
|
|
+ ->find($file->object_id);
|
|
|
+
|
|
|
+ throw_validation_if(! $object, sprintf("File ID: %s, no permission to access", $file->id));
|
|
|
+
|
|
|
+ $fileDownloadResource = (new FileDownloadResource($file))->toArray(request());
|
|
|
+
|
|
|
+ $folderPath = [];
|
|
|
+ foreach(array_filter(explode(",", $file->folder?->path)) as $folderId) {
|
|
|
+ $folderPath[] = $folders->get($folderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ $fileDownloadResource['folder_path'] = "/" . implode('/', $folderPath);
|
|
|
+
|
|
|
+ $items[] = $fileDownloadResource;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $items;
|
|
|
+ }
|
|
|
+}
|