Browse Source

share file store

moell 10 months ago
parent
commit
01b8291f3d

+ 60 - 0
app/Http/Controllers/API/ShareFileController.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App\Http\Controllers\API;
+
+use App\Http\Controllers\Controller;
+use App\Http\Requests\API\ShareFile\CreateRequest;
+use App\Models\Enums\ShareFileObjectType;
+use App\Models\File;
+use App\Models\ShareFile;
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Ramsey\Uuid\Uuid;
+
+class ShareFileController extends Controller
+{
+    public function store(CreateRequest $request)
+    {
+        $objectType = ShareFileObjectType::from($request->object_type);
+
+        $object = $objectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id);
+
+        $objectFields = [
+            'object_type' => ShareFileObjectType::CONTAINER->value,
+            'object_id' => $object->id,
+        ];
+
+        $shareFile = ShareFile::query()->where($objectFields)->first();
+        if ($shareFile) {
+            return $this->badRequest("Please do not re-share");
+        }
+
+        $files = File::query()->where($objectFields)->whereIn("id", $request->file_ids)->pluck("id");
+        if (! $files) {
+            return $this->badRequest("Please select the file you want to share");
+        }
+
+        $expirationTime = match ($request->expiration_time) {
+            0 => null,
+            1 => Carbon::now()->addDay(),
+            2 => Carbon::now()->addWeek(),
+            3 => Carbon::now()->addMonth(),
+        };
+
+        ShareFile::query()->create([
+            ...$request->all(),
+            'created_by' => Auth::id(),
+            'uuid' => Uuid::uuid4(),
+            'files' => $files->toArray(),
+            'expiration_time' => $expirationTime,
+        ]);
+
+        return $this->created();
+    }
+
+    public function destroy(string $id)
+    {
+
+    }
+}

+ 36 - 0
app/Http/Requests/API/ShareFile/CreateRequest.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Http\Requests\API\ShareFile;
+
+use App\Models\Enums\ShareFileObjectType;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Validation\Rules\Enum;
+
+class CreateRequest extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     */
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
+     */
+    public function rules(): array
+    {
+        return [
+            'file_ids' => 'array',
+            'object_id' => 'required',
+            'object_type' => [
+                'required',
+                new Enum(ShareFileObjectType::class),
+            ],
+            'expiration_time' => 'required:0,1,2,3',
+        ];
+    }
+}

+ 54 - 0
app/Models/Enums/ShareFileObjectType.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Models\Enums;
+
+use App\Models\Action;
+use App\Models\Asset;
+use App\Models\Container;
+use App\Models\Plan;
+use App\Models\Project;
+use App\Models\Requirement;
+use App\Models\Task;
+
+enum ShareFileObjectType: string
+{
+    case ASSET = "asset";
+
+    case PROJECT = "project";
+
+    case REQUIREMENT = "requirement";
+
+    case TASK = "task";
+
+    case ACTION = "action";
+
+    case PLAN = "plan";
+
+    case CONTAINER = "container";
+
+    public function modelBuilder(): \Illuminate\Database\Eloquent\Builder
+    {
+        return match ($this) {
+            self::ASSET => Asset::query(),
+            self::PROJECT => Project::query(),
+            self::TASK => Task::query(),
+            self::REQUIREMENT => Requirement::query(),
+            self::ACTION => Action::query(),
+            self::PLAN => Plan::query(),
+            self::CONTAINER => Container::query(),
+        };
+    }
+
+    public function modelBuilderAllowed(string $id = null): \Illuminate\Database\Eloquent\Builder
+    {
+        return match ($this) {
+            self::ASSET => Asset::query(),
+            self::PROJECT => Project::query()->allowed($id),
+            self::TASK => Task::query()->allowed($id),
+            self::REQUIREMENT => Requirement::query(),
+            self::ACTION => Action::query(),
+            self::PLAN => Plan::query(),
+            self::CONTAINER => Container::query()->allowed($id),
+        };
+    }
+}

+ 19 - 0
app/Models/ShareFile.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class ShareFile extends Model
+{
+    use HasFactory;
+
+    protected $fillable = [
+        'object_type', 'object_id', 'uuid', 'files', 'expiration_time', 'created_by'
+    ];
+
+    protected $casts = [
+        'files' => 'array',
+    ];
+}

+ 33 - 0
database/migrations/2024_05_05_125846_create_share_files_table.php

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('share_files', function (Blueprint $table) {
+            $table->id();
+            $table->string("object_type", 30);
+            $table->integer("object_id");
+            $table->string("uuid", 40)->unique();
+            $table->json("files");
+            $table->dateTime("expiration_time")->nullable();
+            $table->integer("created_by");
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('share_files');
+    }
+};

+ 3 - 0
routes/api.php

@@ -170,5 +170,8 @@ Route::middleware(['auth:sanctum'])->group(function () {
         Route::post("notification/mark-as-read", [API\NotificationController::class, "markAsRead"])->name("notification.mark-as-read");
 
         Route::get("container-linkage/{library_id}", [API\ContainerController::class, "linkage"])->name("container.linkage");
+
+        Route::post("share-file", [API\ShareFileController::class, "store"])->name("share-file.store");
+        Route::delete("share-file/{share_file}", [API\ShareFileController::class, "destroy"])->name("share-file.destroy");
     });
 });