Laravel 8.* + Backpack + Article with image (file upload)

#STEP 1: Create migration to add image to an article

php artisan make:migration add_image_to_articles_table --table=articles
/**
* Run the migrations.
*
*
@return void
*/
public function up()
{
Schema::table('articles', function (Blueprint $table) {
$table->string('image',255)->nullable();
});
}

/**
* Reverse the migrations.
*
*
@return void
*/
public function down()
{
Schema::table('articles', function (Blueprint $table) {
$table->dropColumn('image');
});
}
php artisan migrate

#STEP 2: Alter Article model

use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Storage;
public static function boot()
{
parent::boot();
static::deleting(function($obj) {
Storage::delete(Str::replaceFirst('storage/','public/', $obj->image));
});
}



public function setImageAttribute($value)
{
$attribute_name = "image";
// destination path relative to the disk above
$destination_path = "public/articles";

// if the image was erased
if ($value==null) {
// delete the image from disk
Storage::delete($this->{$attribute_name});

// set null in the database column
$this->attributes[$attribute_name] = null;
}

// if a base64 was sent, store it in the db
if (Str::startsWith($value, 'data:image'))
{
// 0. Make the image
$image = Image::make($value)->encode('jpg', 90);

// 1. Generate a filename.
$filename = md5($value.time()).'.jpg';

// 2. Store the image on disk.
Storage::put($destination_path.'/'.$filename, $image->stream());

// 3. Delete the previous image, if there was one.
Storage::delete(Str::replaceFirst('storage/','public/', $this->{$attribute_name}));

// 4. Save the public path to the database
// but first, remove "public/" from the path, since we're pointing to it
// from the root folder; that way, what gets saved in the db
// is the public URL (everything that comes after the domain name)
$public_destination_path = Str::replaceFirst('public/', 'storage/', $destination_path);
$this->attributes[$attribute_name] = $public_destination_path.'/'.$filename;
}
}

#STEP 3: Install intervention/image

Run

composer require intervention/image

#STEP 4: Adjust Article controller

[
'label' => "Article Image",
'name' => "image",
'type' => 'image',
'crop' => true, // set to true to allow cropping, false to disable
'aspect_ratio' => 1, // omit or set to 0 to allow any aspect ratio
]
protected function setupListOperation()
{
$this->crud->set('show.setFromDb', false);
$this->crud->addColumns($this->getFieldsData(TRUE));
}

#STEP 5: Make disk public and allow files to be shown

php artisan storage:link

#STEP 6: Time to test

Adding of an item

Video

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store