diff --git a/app/Filament/Resources/EggResource/Pages/ListEggs.php b/app/Filament/Resources/EggResource/Pages/ListEggs.php index 5a0d649f8..71adf94d7 100644 --- a/app/Filament/Resources/EggResource/Pages/ListEggs.php +++ b/app/Filament/Resources/EggResource/Pages/ListEggs.php @@ -8,6 +8,7 @@ use App\Services\Eggs\Sharing\EggImporterService; use Exception; use Filament\Actions; use Filament\Forms; +use Filament\Forms\Components\Tabs; use Filament\Notifications\Notification; use Filament\Resources\Pages\ListRecords; use Filament\Tables\Table; @@ -62,21 +63,58 @@ class ListEggs extends ListRecords Actions\Action::make('import') ->label('Import') ->form([ - Forms\Components\FileUpload::make('egg') - ->acceptedFileTypes(['application/json']) - ->storeFiles(false) - ->multiple(), + Tabs::make('Tabs') + ->tabs([ + Tabs\Tab::make('From File') + ->icon('tabler-file-upload') + ->schema([ + Forms\Components\FileUpload::make('egg') + ->label('Egg') + ->hint('This should be the json file ( egg-minecraft.json )') + ->acceptedFileTypes(['application/json']) + ->storeFiles(false) + ->multiple(), + ]), + Tabs\Tab::make('From URL') + ->icon('tabler-world-upload') + ->schema([ + Forms\Components\TextInput::make('url') + ->label('URL') + ->hint('This URL should point to a single json file') + ->url(), + ]), + ]) + ->contained(false), + ]) ->action(function (array $data): void { - /** @var TemporaryUploadedFile $eggFile */ - $eggFile = $data['egg']; /** @var EggImporterService $eggImportService */ $eggImportService = resolve(EggImporterService::class); - foreach ($eggFile as $file) { + if (!empty($data['egg'])) { + /** @var TemporaryUploadedFile[] $eggFile */ + $eggFile = $data['egg']; + + foreach ($eggFile as $file) { + try { + $eggImportService->fromFile($file); + } catch (Exception $exception) { + Notification::make() + ->title('Import Failed') + ->danger() + ->send(); + + report($exception); + + return; + } + } + } + + if (!empty($data['url'])) { try { - $eggImportService->handle($file); + $eggImportService->fromUrl($data['url']); } catch (Exception $exception) { Notification::make() ->title('Import Failed') diff --git a/app/Http/Controllers/Admin/Eggs/EggShareController.php b/app/Http/Controllers/Admin/Eggs/EggShareController.php index ffec4aad5..e938403db 100644 --- a/app/Http/Controllers/Admin/Eggs/EggShareController.php +++ b/app/Http/Controllers/Admin/Eggs/EggShareController.php @@ -46,7 +46,7 @@ class EggShareController extends Controller */ public function import(EggImportFormRequest $request): RedirectResponse { - $egg = $this->importerService->handle($request->file('import_file')); + $egg = $this->importerService->fromFile($request->file('import_file')); $this->alert->success(trans('admin/eggs.notices.imported'))->flash(); return redirect()->route('admin.eggs.view', ['egg' => $egg->id]); @@ -61,7 +61,7 @@ class EggShareController extends Controller */ public function update(EggImportFormRequest $request, Egg $egg): RedirectResponse { - $this->updateImporterService->handle($egg, $request->file('import_file')); + $this->updateImporterService->fromFile($egg, $request->file('import_file')); $this->alert->success(trans('admin/eggs.notices.updated_via_import'))->flash(); return redirect()->route('admin.eggs.view', ['egg' => $egg]); diff --git a/app/Services/Eggs/Sharing/EggImporterService.php b/app/Services/Eggs/Sharing/EggImporterService.php index 23ef0c819..5c94ec2fa 100644 --- a/app/Services/Eggs/Sharing/EggImporterService.php +++ b/app/Services/Eggs/Sharing/EggImporterService.php @@ -9,6 +9,7 @@ use Illuminate\Http\UploadedFile; use App\Models\EggVariable; use Illuminate\Database\ConnectionInterface; use App\Services\Eggs\EggParserService; +use Spatie\TemporaryDirectory\TemporaryDirectory; class EggImporterService { @@ -21,7 +22,7 @@ class EggImporterService * * @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable */ - public function handle(UploadedFile $file): Egg + public function fromFile(UploadedFile $file): Egg { $parsed = $this->parser->handle($file); @@ -46,4 +47,19 @@ class EggImporterService }); } + /** + * Take an url and parse it into a new egg. + * + * @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable + */ + public function fromUrl(string $url): Egg + { + $info = pathinfo($url); + $tmpDir = TemporaryDirectory::make()->deleteWhenDestroyed(); + $tmpPath = $tmpDir->path($info['basename']); + + file_put_contents($tmpPath, file_get_contents($url)); + + return $this->fromFile(new UploadedFile($tmpPath, $info['basename'], 'application/json')); + } } diff --git a/app/Services/Eggs/Sharing/EggUpdateImporterService.php b/app/Services/Eggs/Sharing/EggUpdateImporterService.php index f2123e1f4..a441079e5 100644 --- a/app/Services/Eggs/Sharing/EggUpdateImporterService.php +++ b/app/Services/Eggs/Sharing/EggUpdateImporterService.php @@ -8,6 +8,7 @@ use Illuminate\Support\Collection; use App\Models\EggVariable; use Illuminate\Database\ConnectionInterface; use App\Services\Eggs\EggParserService; +use Spatie\TemporaryDirectory\TemporaryDirectory; class EggUpdateImporterService { @@ -23,7 +24,7 @@ class EggUpdateImporterService * * @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable */ - public function handle(Egg $egg, UploadedFile $file): Egg + public function fromFile(Egg $egg, UploadedFile $file): Egg { $parsed = $this->parser->handle($file); @@ -47,4 +48,20 @@ class EggUpdateImporterService return $egg->refresh(); }); } + + /** + * Update an existing Egg using an url. + * + * @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable + */ + public function fromUrl(Egg $egg, string $url): Egg + { + $info = pathinfo($url); + $tmpDir = TemporaryDirectory::make()->deleteWhenDestroyed(); + $tmpPath = $tmpDir->path($info['basename']); + + file_put_contents($tmpPath, file_get_contents($url)); + + return $this->fromFile($egg, new UploadedFile($tmpPath, $info['basename'], 'application/json')); + } } diff --git a/composer.json b/composer.json index 45213c015..399b42278 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "s1lentium/iptools": "~1.2.0", "spatie/laravel-fractal": "^6.2", "spatie/laravel-query-builder": "^5.8.1", + "spatie/temporary-directory": "^2.2", "symfony/http-client": "^7.1", "symfony/mailgun-mailer": "^7.1", "symfony/postmark-mailer": "^7.0.7", diff --git a/composer.lock b/composer.lock index 5a5c53536..3b1006ea4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8feeafbeb16044bd6716510a73393fc0", + "content-hash": "bf44faee3aae2b1d4c1b57893c1aba98", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -6990,6 +6990,67 @@ ], "time": "2024-05-10T08:19:35+00:00" }, + { + "name": "spatie/temporary-directory", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/temporary-directory.git", + "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a", + "reference": "76949fa18f8e1a7f663fd2eaa1d00e0bcea0752a", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\TemporaryDirectory\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily create, use and destroy temporary directories", + "homepage": "https://github.com/spatie/temporary-directory", + "keywords": [ + "php", + "spatie", + "temporary-directory" + ], + "support": { + "issues": "https://github.com/spatie/temporary-directory/issues", + "source": "https://github.com/spatie/temporary-directory/tree/2.2.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-12-25T11:46:58+00:00" + }, { "name": "symfony/clock", "version": "v7.0.7", @@ -13096,5 +13157,5 @@ "ext-zip": "*" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/database/Seeders/EggSeeder.php b/database/Seeders/EggSeeder.php index efdfc8f04..afcb55a6d 100644 --- a/database/Seeders/EggSeeder.php +++ b/database/Seeders/EggSeeder.php @@ -75,10 +75,10 @@ class EggSeeder extends Seeder ->first(); if ($egg instanceof Egg) { - $this->updateImporterService->handle($egg, $file); + $this->updateImporterService->fromFile($egg, $file); $this->command->info('Updated ' . $decoded['name']); } else { - $this->importerService->handle($file); + $this->importerService->fromFile($file); $this->command->comment('Created ' . $decoded['name']); } }