diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 802dc83..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,18 +0,0 @@ -risky: true - -preset: laravel - -enabled: - - strict - - unalign_double_arrow - -disabled: - - short_array_syntax - -finder: - exclude: - - "public" - - "resources" - - "tests" - name: - - "*.php" diff --git a/composer.json b/composer.json index a6fa8a8..470ddb8 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,9 @@ } ], "require": { - "laravel-enso/core": "^8.0", - "laravel-enso/helpers": "^2.0", + "laravel-enso/core": "^9.0", + "laravel-enso/helpers": "^3.0", + "laravel-enso/dynamic-methods": "^3.0", "laravel-enso/image-transformer": "^2.0", "laravel-enso/migrator": "^2.0", "laravel-enso/track-who": "^2.0" @@ -36,8 +37,7 @@ "laravel": { "providers": [ "LaravelEnso\\Files\\AppServiceProvider", - "LaravelEnso\\Files\\AuthServiceProvider", - "LaravelEnso\\Files\\EnumServiceProvider" + "LaravelEnso\\Files\\AuthServiceProvider" ] } } diff --git a/database/migrations/2017_01_01_112500_create_structure_for_uploads.php b/database/migrations/2017_01_01_112500_create_structure_for_uploads.php index 08e9ec0..a34ef04 100644 --- a/database/migrations/2017_01_01_112500_create_structure_for_uploads.php +++ b/database/migrations/2017_01_01_112500_create_structure_for_uploads.php @@ -2,10 +2,9 @@ use LaravelEnso\Migrator\Database\Migration; -return new class extends Migration -{ +return new class extends Migration { protected array $permissions = [ - ['name' => 'core.uploads.store', 'description' => 'Upload file', 'is_default' => true], - ['name' => 'core.uploads.destroy', 'description' => 'Delete upload', 'is_default' => true], + ['name' => 'core.files.uploads.store', 'description' => 'Upload file', 'is_default' => true], + ['name' => 'core.files.uploads.destroy', 'description' => 'Delete upload', 'is_default' => true], ]; }; diff --git a/routes/api.php b/routes/api.php index 6a1cb74..38843c4 100644 --- a/routes/api.php +++ b/routes/api.php @@ -8,7 +8,6 @@ ->as('core.') ->group(function () { require __DIR__.'/app/files.php'; - require __DIR__.'/app/uploads.php'; }); Route::middleware(['api', 'auth', 'core']) diff --git a/routes/app/files.php b/routes/app/files.php index 36e6594..c3ba4cd 100644 --- a/routes/app/files.php +++ b/routes/app/files.php @@ -29,4 +29,6 @@ Route::patch('makePublic/{file}', MakePublic::class)->name('makePublic'); Route::patch('makePrivate/{file}', MakePrivate::class)->name('makePrivate'); Route::patch('favorite/{file}', Favorite::class)->name('favorite'); + + require __DIR__.'/files/uploads.php'; }); diff --git a/routes/app/uploads.php b/routes/app/files/uploads.php similarity index 68% rename from routes/app/uploads.php rename to routes/app/files/uploads.php index 4315f9a..2612501 100644 --- a/routes/app/uploads.php +++ b/routes/app/files/uploads.php @@ -1,8 +1,8 @@ as('uploads.') diff --git a/src/AppServiceProvider.php b/src/AppServiceProvider.php index 0e943e6..13242e1 100644 --- a/src/AppServiceProvider.php +++ b/src/AppServiceProvider.php @@ -3,9 +3,6 @@ namespace LaravelEnso\Files; use Illuminate\Support\ServiceProvider; -use LaravelEnso\DynamicMethods\Services\Methods; -use LaravelEnso\Files\Dynamics\Relations\FavoriteFiles; -use LaravelEnso\Users\Models\User; class AppServiceProvider extends ServiceProvider { @@ -13,8 +10,6 @@ public function boot() { $this->load() ->publish(); - - Methods::bind(User::class, [FavoriteFiles::class]); } private function load() diff --git a/src/Dynamics/Relations/FavoriteFiles.php b/src/Dynamics/FavoriteFiles.php similarity index 55% rename from src/Dynamics/Relations/FavoriteFiles.php rename to src/Dynamics/FavoriteFiles.php index feb3954..2ae3e21 100644 --- a/src/Dynamics/Relations/FavoriteFiles.php +++ b/src/Dynamics/FavoriteFiles.php @@ -1,14 +1,20 @@ $this->hasManyThrough( + return fn (User $model) => $model->hasManyThrough( File::class, Favorite::class, 'user_id', diff --git a/src/EnumServiceProvider.php b/src/EnumServiceProvider.php deleted file mode 100644 index 10c809f..0000000 --- a/src/EnumServiceProvider.php +++ /dev/null @@ -1,13 +0,0 @@ - TemporaryLinkDuration::class, - ]; -} diff --git a/src/Enums/TemporaryLinkDuration.php b/src/Enums/TemporaryLinkDuration.php index e06395b..fe5e164 100644 --- a/src/Enums/TemporaryLinkDuration.php +++ b/src/Enums/TemporaryLinkDuration.php @@ -2,20 +2,25 @@ namespace LaravelEnso\Files\Enums; -use LaravelEnso\Enums\Services\Enum; +use LaravelEnso\Enums\Contracts\Frontend; -class TemporaryLinkDuration extends Enum +enum TemporaryLinkDuration: int implements Frontend { - public const FiveMinutes = 5 * 60; - public const OneHour = 60 * 60; - public const OneDay = 60 * 60 * 24; + case FiveMinutes = 5 * 60; + case OneHour = 60 * 60; + case OneDay = 60 * 60 * 24; - public static function data(): array + public function label(): string { - return [ + return match ($this) { self::FiveMinutes => '5m', self::OneHour => '1h', self::OneDay => '24h', - ]; + }; + } + + public static function registerBy(): string + { + return 'temporaryLinkDuration'; } } diff --git a/src/Http/Controllers/Upload/Destroy.php b/src/Http/Controllers/File/Upload/Destroy.php similarity index 85% rename from src/Http/Controllers/Upload/Destroy.php rename to src/Http/Controllers/File/Upload/Destroy.php index 9014d95..9dd8c95 100644 --- a/src/Http/Controllers/Upload/Destroy.php +++ b/src/Http/Controllers/File/Upload/Destroy.php @@ -1,6 +1,6 @@ 'required|in:'.TemporaryLinkDuration::keys()->implode(','), + 'seconds' => ['required', (new Enum(TemporaryLinkDuration::class))], ]; } } diff --git a/src/Upgrades/AddTypeIdCreatedAtIndex.php b/src/Upgrades/AddTypeIdCreatedAtIndex.php deleted file mode 100644 index 8384626..0000000 --- a/src/Upgrades/AddTypeIdCreatedAtIndex.php +++ /dev/null @@ -1,30 +0,0 @@ - $table - ->index(['type_id', 'created_at'])); - } -} diff --git a/src/Upgrades/CreatedAtIndex.php b/src/Upgrades/CreatedAtIndex.php deleted file mode 100644 index b39ac1e..0000000 --- a/src/Upgrades/CreatedAtIndex.php +++ /dev/null @@ -1,20 +0,0 @@ - $table->index(['created_at'])); - } -} diff --git a/src/Upgrades/DropMorphFile.php b/src/Upgrades/DropMorphFile.php deleted file mode 100644 index 0bacf0d..0000000 --- a/src/Upgrades/DropMorphFile.php +++ /dev/null @@ -1,30 +0,0 @@ -string('attachable_type')->nullable()->change(); - $table->unsignedBigInteger('attachable_id')->nullable()->change(); - }); - } -} diff --git a/src/Upgrades/DropMorphModels.php b/src/Upgrades/DropMorphModels.php deleted file mode 100644 index 41113ae..0000000 --- a/src/Upgrades/DropMorphModels.php +++ /dev/null @@ -1,111 +0,0 @@ -needUpgrade()->isEmpty(); - } - - public function migrateTable(): void - { - Model::unsetEventDispatcher(); - - $this->needUpgrade() - ->each(fn ($model, $morphKey) => $this->process($model, $morphKey)); - } - - private function process(string $model, string $morphKey) - { - $this->addForeignKey($model) - ->migrateData($model, $morphKey); - } - - private function addForeignKey(string $model): self - { - $table = $this->table($model); - $after = $this->afterColumn($table); - - Schema::table($table, function (Blueprint $table) use ($after) { - $table->unsignedBigInteger('file_id')->nullable()->after($after); - $table->foreign('file_id')->references('id')->on('files') - ->onUpdate('restrict')->onDelete('restrict'); - }); - - return $this; - } - - private function migrateData(string $model, string $morphKey) - { - $files = File::whereAttachableType($morphKey); - $type = Type::for($model); - $files->each(fn ($file) => $this->migrateFile($type, $file, $model)); - } - - private function migrateFile(Type $type, File $file, string $model) - { - $folder = Str::of($file->saved_name)->beforeLast('/'); - $savedName = Str::of($file->saved_name)->replace("{$folder}/", ''); - - $file->update([ - 'type_id' => $type->id, - 'saved_name' => $savedName, - ]); - - $record = $model::find($file->attachable_id); - - if ($record) { - $record->update(['file_id' => $file->id]); - } else { - Log::notice("File with id of {$file->id} is missing its morphed model"); - } - } - - private function afterColumn(string $table): string - { - return Collection::wrap(Schema::getColumnListing($table)) - ->filter(fn ($column) => Str::endsWith($column, '_id')) - ->last() ?? 'id'; - } - - private function needUpgrade(): Collection - { - $upgraded = fn ($model) => Table::hasColumn($this->table($model), 'file_id'); - - return $this->models()->reject($upgraded); - } - - private function table(string $model): string - { - return (new $model())->getTable(); - } - - private function models(): Collection - { - $upgrade = Config::get('enso.files.upgrade'); - - return Collection::wrap($upgrade) - ->filter(fn ($model) => class_exists($model)); - } -} diff --git a/src/Upgrades/DropOldIndex.php b/src/Upgrades/DropOldIndex.php deleted file mode 100644 index f507dbe..0000000 --- a/src/Upgrades/DropOldIndex.php +++ /dev/null @@ -1,22 +0,0 @@ - $table->dropIndex(self::Index)); - } -} diff --git a/src/Upgrades/FileIds.php b/src/Upgrades/FileIds.php deleted file mode 100644 index b999f4b..0000000 --- a/src/Upgrades/FileIds.php +++ /dev/null @@ -1,21 +0,0 @@ - $table->id()->change()); - } -} diff --git a/src/Upgrades/FileIsPublic.php b/src/Upgrades/FileIsPublic.php deleted file mode 100644 index c09deea..0000000 --- a/src/Upgrades/FileIsPublic.php +++ /dev/null @@ -1,29 +0,0 @@ - $table - ->boolean('is_public')->nullable()->after('mime_type')); - } - - public function migrateData(): void - { - File::whereNull('is_public')->update(['is_public' => false]); - } -} diff --git a/src/Upgrades/FileType.php b/src/Upgrades/FileType.php deleted file mode 100644 index 5f57d64..0000000 --- a/src/Upgrades/FileType.php +++ /dev/null @@ -1,30 +0,0 @@ -unsignedBigInteger('type_id')->nullable()->after('id'); - $table->foreign('type_id')->references('id')->on('file_types'); - }); - } -} diff --git a/src/Upgrades/MakeFileIdUnique.php b/src/Upgrades/MakeFileIdUnique.php deleted file mode 100644 index d37076e..0000000 --- a/src/Upgrades/MakeFileIdUnique.php +++ /dev/null @@ -1,62 +0,0 @@ -needUpgrade()->isEmpty(); - } - - public function migrateTable(): void - { - Model::unsetEventDispatcher(); - - $this->needUpgrade()->each(fn ($model) => $this->upgrade($model)); - } - - private function upgrade(string $model): void - { - $table = $this->table($model); - - Schema::table($table, fn ($table) => $table->unique('file_id')); - } - - private function needUpgrade(): Collection - { - $upgraded = fn ($model) => Table::hasIndex( - $this->table($model), - "{$this->table($model)}_file_id_unique" - ); - - return $this->models()->reject($upgraded); - } - - private function table(string $model): string - { - return (new $model())->getTable(); - } - - private function models(): Collection - { - $upgrade = Config::get('enso.files.upgrade'); - - return Collection::wrap($upgrade) - ->filter(fn ($model) => class_exists($model)); - } -} diff --git a/src/Upgrades/MoveFiles.php b/src/Upgrades/MoveFiles.php deleted file mode 100644 index ca004b3..0000000 --- a/src/Upgrades/MoveFiles.php +++ /dev/null @@ -1,93 +0,0 @@ -nonStandardFolders = Config::get('enso.files.nonStandardFolders'); - $this->renameFolders = Config::get('enso.files.renameFolders'); - } - - public function isMigrated(): bool - { - return Table::hasColumn('files', 'saved_name') - && $this->notMoved()->doesntExist(); - } - - public function migrateData(): void - { - $this->notMoved() - ->pluck('attachable_type') - ->unique() - ->each(fn ($attachable) => $this->handle($attachable)); - - $this->cleanup(); - } - - private function handle(string $attachable): void - { - $key = $this->renameFolders[$attachable] ?? $attachable; - $folder = Str::plural($key); - - if (! Storage::has($folder)) { - Storage::makeDirectory($folder); - } - - File::whereAttachableType($attachable) - ->each(fn ($file) => $this->move($file, $folder)); - - $this->replace($attachable, $folder); - } - - private function move(File $file, string $folder): void - { - if (Storage::exists($file->saved_name)) { - $location = Str::replace($this->nonStandardFolders, $folder, $file->saved_name); - - if ($file->saved_name !== $location) { - Storage::move($file->saved_name, $location); - } - } - } - - private function replace(string $attachable, string $folder) - { - Collection::wrap($this->nonStandardFolders) - ->each(fn ($from) => $this->notMoved() - ->whereAttachableType($attachable) - ->where('saved_name', 'LIKE', "{$from}/%") - ->update(['saved_name' => DB::raw("REPLACE(saved_name, '{$from}', '{$folder}')")])); - } - - private function notMoved(): Builder - { - $build = fn ($query) => Collection::wrap($this->nonStandardFolders) - ->reduce(fn ($files, $folder) => $files - ->orWhere('saved_name', 'LIKE', "{$folder}/%"), $query); - - return File::where($build); - } - - private function cleanup(): void - { - Collection::wrap($this->nonStandardFolders) - ->filter(fn ($folder) => count(Storage::files($folder)) === 0) - ->each(fn ($folder) => Storage::deleteDirectory($folder)); - } -} diff --git a/src/Upgrades/Permissions.php b/src/Upgrades/Permissions.php deleted file mode 100644 index 86d4572..0000000 --- a/src/Upgrades/Permissions.php +++ /dev/null @@ -1,21 +0,0 @@ - 'core.files.favorite', 'description' => 'Toggle file as favorite', 'is_default' => true], - ['name' => 'core.files.browse', 'description' => 'Browse file type', 'is_default' => true], - ['name' => 'core.files.recent', 'description' => 'Browse recent files', 'is_default' => true], - ['name' => 'core.files.favorites', 'description' => 'Browse favorites files', 'is_default' => true], - ['name' => 'core.files.makePublic', 'description' => 'Make file public', 'is_default' => true], - ['name' => 'core.files.makePrivate', 'description' => 'Make file private', 'is_default' => true], - ['name' => 'core.files.update', 'description' => 'Update file name', 'is_default' => true], - ]; -} diff --git a/src/Upgrades/RenameFilePath.php b/src/Upgrades/RenameFilePath.php deleted file mode 100644 index f1ff4fb..0000000 --- a/src/Upgrades/RenameFilePath.php +++ /dev/null @@ -1,28 +0,0 @@ - $table - ->renameColumn('path', 'saved_name')); - } -} diff --git a/src/Upgrades/TypeSeeder.php b/src/Upgrades/TypeSeeder.php deleted file mode 100644 index 8eae1f6..0000000 --- a/src/Upgrades/TypeSeeder.php +++ /dev/null @@ -1,27 +0,0 @@ -exists(); - } - - public function migrateData(): void - { - $seeder = Seeder::class; - - Artisan::call('db:seed', [ - '--class' => $seeder, - '--force' => true, - ]); - } -} diff --git a/src/Upgrades/UpdateMigrationOrder.php b/src/Upgrades/UpdateMigrationOrder.php deleted file mode 100644 index 64d88fc..0000000 --- a/src/Upgrades/UpdateMigrationOrder.php +++ /dev/null @@ -1,47 +0,0 @@ - '2017_01_01_112100_create_file_types_table', - '2018_08_25_100000_create_files_table' => '2017_01_01_112200_create_files_table', - '2018_08_25_101000_create_structure_for_files' => '2017_01_01_112300_create_structure_for_files', - '2018_08_25_102000_create_uploads_table' => '2017_01_01_112400_create_uploads_table', - '2018_08_25_103000_create_structure_for_uploads' => '2017_01_01_112500_create_structure_for_uploads', - '2022_01_17_100000_create_favorite_files_table' => '2017_01_01_112600_create_favorite_files_table', - '2022_01_23_101000_create_structure_for_file_types' => '2017_01_01_129000_create_structure_for_file_types', - ]; - - private Collection $mapping; - - public function __construct() - { - $this->mapping = Collection::wrap(self::Mapping); - } - - public function isMigrated(): bool - { - return DB::table('migrations') - ->whereIn('migration', $this->mapping->keys()) - ->doesntExist(); - } - - public function migrateData(): void - { - $this->mapping->each(fn ($to, $from) => $this->update($from, $to)); - } - - private function update($from, $to): void - { - DB::table('migrations') - ->whereMigration($from) - ->update(['migration' => $to]); - } -} diff --git a/src/Upgrades/UpdateUploadsPermissions.php b/src/Upgrades/UpdateUploadsPermissions.php new file mode 100644 index 0000000..e2686c9 --- /dev/null +++ b/src/Upgrades/UpdateUploadsPermissions.php @@ -0,0 +1,44 @@ + 'core.files.store', + 'core.files.uploads.destroy' => 'core.files.destroy', + ]; + + public function __construct() + { + $this->mapping = Collection::wrap(self::Mapping); + } + + public function isMigrated(): bool + { + return Permission::whereIn('name', $this->mapping->keys())->exists(); + } + + public function migrateData(): void + { + $this->mapping->each(fn ($from, $to) => $this->update($from, $to)); + + Role::where('name', '<>', Config::get('enso.config.defaultRole')) + ->get() + ->each + ->writeConfig(); + } + + private function update($from, $to): void + { + Permission::whereName($from)->update(['migration' => $to]); + } +}