Sitemap

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

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

Article
- 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
Press enter or click to view image in full size
/**
* 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');
});
}

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.

Press enter or click to view image in full size

#STEP 2: Alter Article model

Press enter or click to view image in full size

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()
{
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;
}
}

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

Run

composer require intervention/image

#STEP 4: Adjust Article controller

Press enter or click to view image in full size
[
'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->crud->addColumns($this->getFieldsData(TRUE));
}

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
Press enter or click to view image in full size

#STEP 6: Time to test

Adding of an item

Press enter or click to view image in full size

Edit of an item

Press enter or click to view image in full size

List items table

Press enter or click to view image in full size

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

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

Video

--

--

Lyubomir Filipov
Lyubomir Filipov

Written by Lyubomir Filipov

Group Architect at FFW, believer, developer, enthusiast

Responses (2)