|
@@ -0,0 +1,151 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services\Folder;
|
|
|
+
|
|
|
+use App\Models\Enums\FolderObjectType;
|
|
|
+use App\Models\File;
|
|
|
+use App\Models\Folder;
|
|
|
+use Illuminate\Database\Eloquent\Collection;
|
|
|
+
|
|
|
+class VersionFileTreeByObjectService {
|
|
|
+ protected FolderObjectType $folderObjectType;
|
|
|
+
|
|
|
+ protected $object;
|
|
|
+
|
|
|
+ protected array $objectWhere = [];
|
|
|
+
|
|
|
+ protected array $fileWhere = [];
|
|
|
+
|
|
|
+ protected int $objectVersion = 0;
|
|
|
+
|
|
|
+ protected array $fileIds = [];
|
|
|
+
|
|
|
+ protected array $folderIds = [];
|
|
|
+
|
|
|
+
|
|
|
+ public function __construct(protected array $queryData, string $objectType, string $objectId)
|
|
|
+ {
|
|
|
+ $this->folderObjectType = FolderObjectType::from($objectType);
|
|
|
+
|
|
|
+ $this->object = $this->folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
|
|
|
+
|
|
|
+ $this->objectWhere = ['object_type' => $objectType, 'object_id' => $objectId,];
|
|
|
+
|
|
|
+ $this->fileWhere = [];
|
|
|
+ if (($this->queryData['show_hide'] ?? null) != 1) {
|
|
|
+ $this->fileWhere['is_hide'] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->objectVersion = $this->queryData['object_version'] ?? 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function versionFileTreeByObject()
|
|
|
+ {
|
|
|
+ $this->containerDataLoad();
|
|
|
+
|
|
|
+ $folders = $this->queryFolders();
|
|
|
+
|
|
|
+ $nodes = [];
|
|
|
+
|
|
|
+ foreach ($folders as &$folder) {
|
|
|
+ $nodes[] = [
|
|
|
+ 'id' => $folder->id,
|
|
|
+ 'node_id' => $folder->id,
|
|
|
+ 'name' => $folder->name,
|
|
|
+ 'parent_id' => $folder->parent_id,
|
|
|
+ 'type' => 'folder',
|
|
|
+ ];
|
|
|
+
|
|
|
+ $this->filesFormat($folder->files, $folder->id, $nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ $topFiles = $this->queryTopFiles();
|
|
|
+
|
|
|
+ $this->filesFormat($topFiles, 0, $nodes);
|
|
|
+
|
|
|
+ return make_tree($nodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function queryTopFiles()
|
|
|
+ {
|
|
|
+ return File::query()->where($this->objectWhere)
|
|
|
+ ->where("source", 1)
|
|
|
+ ->where("folder_id", 0)
|
|
|
+ ->when($this->fileWhere, fn($query) => $query->where($this->fileWhere))
|
|
|
+ ->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds))
|
|
|
+ ->where(fn($query) => $query->where($this->fileWhere)->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds)))
|
|
|
+ ->orderByDesc("version")
|
|
|
+ ->get();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function queryFolders()
|
|
|
+ {
|
|
|
+ return Folder::query()
|
|
|
+ ->with([
|
|
|
+ 'files' => fn($query) => $query->when($this->fileWhere, fn($query) => $query->where($this->fileWhere))
|
|
|
+ ->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds)),
|
|
|
+ 'files.createdBy'
|
|
|
+ ])
|
|
|
+ ->when($this->folderIds, fn($query) => $query->whereIn("id", $this->folderIds))
|
|
|
+ ->where($this->objectWhere)
|
|
|
+ ->get(['id', 'name', 'parent_id']);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function filesFormat(Collection $files, $firstId, &$nodes)
|
|
|
+ {
|
|
|
+ foreach ($files->groupBy("title") as $fileItems) {
|
|
|
+ $item = $this->fileResourceFormat($fileItems->first(), $firstId, false);
|
|
|
+ $nodes[] = $item;
|
|
|
+
|
|
|
+ foreach ($fileItems as $fileItem) {
|
|
|
+ $nodes[] = $this->fileResourceFormat($fileItem, $item['id'], true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function fileResourceFormat(File $file, $parentId, bool $isChildrenFile)
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ 'id' => sprintf($isChildrenFile ? "children_%s" : "file_%s", $file->id),
|
|
|
+ 'node_id' => $file->id,
|
|
|
+ 'parent_id' => $parentId,
|
|
|
+ 'title' => $file->title,
|
|
|
+ 'extension' => $file->extension,
|
|
|
+ 'size' => $file->size,
|
|
|
+ 'created_by' => $file->createdBy ? [
|
|
|
+ 'id' => $file->createdBy->id,
|
|
|
+ 'name' => $file->createdBy->name,
|
|
|
+ 'username' => $file->createdBy->username,
|
|
|
+ ] : [],
|
|
|
+ 'created_at' => (string)$file->created_at,
|
|
|
+ 'version' => $file->version,
|
|
|
+ 'type' => 'file',
|
|
|
+ 'hide' => $file->hide_object_version == 0 ? (bool)$file->is_hide : $file->is_hide && $file->hide_object_version <= $this->objectVersion
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function containerDataLoad(): void
|
|
|
+ {
|
|
|
+ if ($this->folderObjectType != FolderObjectType::CONTAINER) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $containerContent = $this->object->content($this->queryData['object_version'] ?? $this->object->version)->first();
|
|
|
+
|
|
|
+ throw_validation_if(! $containerContent, "The current version does not exist");
|
|
|
+
|
|
|
+ $this->fileIds = explode(",", $containerContent->files);
|
|
|
+
|
|
|
+ if ($this->fileIds) {
|
|
|
+ $containerFolders = File::query()->whereIn("id", $this->fileIds)->pluck("folder_id")->filter()->unique();
|
|
|
+
|
|
|
+ Folder::query()->whereIn("id", $containerFolders->toArray())->pluck("path")->each(function ($item) {
|
|
|
+ $this->folderIds = [...$this->folderIds, ...explode(",", trim($item, ","))];
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (! $this->objectVersion) {
|
|
|
+ $this->objectVersion = $this->object->version;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|