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

Lyubomir Filipov
4 min readDec 19, 2020


In order to proceed you should have:
- Laravel installed + Backpack admin (teaching purposes)
- Tags CRUD created
- Article CRUD created
- virtual host ready for you
- xampp setup or other web server
- composer installed

- title — 255 symbols
- content — text — RichTextEditor
- tags (many available) — select with multiple options

New tutorial to add file upload to the artilce
- image (one image) — image 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) {

* Reverse the migrations.
@return void
public function down()
Schema::table('articles', function (Blueprint $table) {

We are adding a new column image — which will be used to store the url of the image. Next step is to run the migration.

php artisan migrate

Expected result.

#STEP 2: Alter Article model

We need to add extra items to use:

use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Storage;

And then add two functions in FUNCTIONS section.

public static function 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

// 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;

First function will make sure that once we delete an entry — the file will be deleted as well.

Second function is a mutator responsible for the upload the image to the correct folder.

We have logic replacing /public folder with /storage folder due to the fact that images are exposed to end users using /storage folder.

#STEP 3: Install intervention/image


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

We need to adjust getFieldsData function and add the image column.

Our next change is related to setupListOperation method. We need to update it to the following

protected function setupListOperation()
$this->crud->set('show.setFromDb', false);

This will make sure that when we are adding images they will be shown on list as well.

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

php artisan storage:link

#STEP 6: Time to test

Adding of an item

Edit of an item

List items table

Note: Files are uploaded to storage/app/public/articles

But they are available to the end users by accessing — DOMAIN/storage/articles/{IMAGE_NAME}




Lyubomir Filipov

Group Architect at FFW, believer, developer, enthusiast