Floris
Floris

Reputation: 3135

Running cleanup method before migrate:fresh to remove old images from storage

I would like to cleanup the locally seeded storage images when running php artisan migrate:fresh --seed.

I noticed that all the database tables get dropped before the seeders even start. So my method for cleaning up local storage images was never touched:

private function cleanLocalFileSystem()
{
    $files = File::all();
    $files->each(function (File $file) {
        $this->fileController->destroy($file->id); // removes associated files from storage.
    });
}

So there must be a way to clear out theses images at the start of running the migrate:fresh --seed command.

Right?

Upvotes: 0

Views: 62

Answers (3)

ekkev
ekkev

Reputation: 56

If you store uploaded files in 'storage/app/images', and the info about them in table 'images' you can easily remove all your test files and rows (including orphaned files) like this:

use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\DB;

File::cleanDirectory(storage_path('app/images'));
DB::table('images')->truncate();

Upvotes: 0

Floris
Floris

Reputation: 3135

I ended up solving this issue myself before the solultion of @mamaye came in.

I made a .bat file in my Apache bin directory named refreshdb. These are it's contents:

php artisan storage:clear
php artisan migrate:fresh --seed

Then I made the command with php artisan make:command ClearStorage.

<?php

namespace App\Console\Commands;

use App\Http\Controllers\Dashboard\FileController;
use App\Models\File;
use Illuminate\Console\Command;
use Intervention\Image\Exception\NotFoundException;

class ClearStorageCommand extends Command {

    protected $signature = 'storage:clear';
    protected $description = 'Clears all seeder images from storage';
    private FileController $fileController;

    public function __construct()
    {
       parent::__construct();

       $this->fileController = new FileController();
    }

    public function handle()
    {
        try {
            $this->cleanLocalFileSystem();
        } catch (\Exception $exception) {
            $this->error("Failed to clear storage with message: " . $exception->getMessage());
        }

        $this->info('Successfully cleared storage');
    }

    private function cleanLocalFileSystem()
    {
        $files = File::all();

        $files->each(function (File $file) {
            $success = $this->fileController->destroy($file->id);

            if (!$success) {
                throw new NotFoundException('Could not clear file: ' . $file->path . '/' . $file->name);
            }
        });
    }
}

Now I can simply run the refreshdb command in the terminal and all is well.

Again, this is simular to mamaye's solution but it worked for me.

Upvotes: 0

mamaye
mamaye

Reputation: 1064

I suggest you create a custom artisan command on your project since Laravel may not have a direct command to handle it. So the idea is so allow you clean up before you migrate.

https://laravel.com/docs/11.x/artisan#registering-commands

php artisan make:command CleanupThenMigrate

Next, you write your logic for the created command. Go to app/Console/Commands/CleanupThenMigrate.php

**

<?php
    namespace App\Console\Commands;
    use Illuminate\Console\Command;
    use Illuminate\Support\Facades\File;
    use Illuminate\Support\Facades\Storage;
    
class CleanupThenMigrate extends Command
    {
        protected $signature = 'app:cleanup-then-migrate';
        protected $description = '';
        /**
         * Execute the console command.
         */
        public function handle()
        {
            //
            $this->info('Cleaning up local storage images...');
            $this->cleanLocalFileSystem();
            // Run migrations and seeders
            $this->info('Running migrate:fresh...');
            $this->call('migrate:fresh');
            $this->info('Seeding the database...');
            $this->call('db:seed');
            $this->info('Hala Madrid! All local images have been deleted. Migration and Seeding is complete too!');
        }
        private function cleanLocalFileSystem()
        {
            // Define your local storage path
            $storagePath = storage_path('app/public');
            // Delete all files in the storage path
            $getFiles = File::allFiles($storagePath);
            foreach ($getFiles as $file) {
                File::delete($file);
            }
        }
    }

**

Next, run php artisan app:cleanup-then-migrate

I hope this helps.

Upvotes: 1

Related Questions