I'm having a similar problem. This uploaded image handling code gets duplicated in edit
method, and in my dummy data seeder.
I already have a separate class for images in a belongsTo/hasMany relationship to article class, because I have several of them attached to the article. So I thought maybe I should add a couple named constructors to the class to make images from UploadedFile
objects, and from, say, raw image file content (mostly for dummy data seeder, but also for cases of images fetched from URLs).
So, controller would look something like this:
$inputs = $request->only(['name', 'desc', 'date']);
$article = Article::create($inputs);
AttachedImage::fromUploadedFile($request->file('image'))->article()->associate($article);
And similarly in dummy data seeder:
$article = Article::create( ['title' => 'Test title', 'content' => 'goes here'] );
$imageFileName = 'my-test-file.jpg';
AttachedImage::fromFileContent(file_get_contents($imageFileName))->article()->associate($article);
But I'm not particularly keen on the idea of models knowing the rules of making unique file names and the location of image directory.
There has to be a better way.
Well i decided to put my image manipulations directly in the model in an mutator like this :
public function setImageAttribute($image) {
$this->deleteCover();
$image_name = uniqid('cover_').'.'.$image->guessExtension();
$new_image = \Image::make($image->getRealPath())
->resize(200,200, function($c) {
$c->aspectRatio();
})
->save($this->image_path.$image_name);
$this->attributes['image'] = $image_name;
}
public function deleteCover() {
if($this->image) {
unlink($this->image_path.$this->image);
}
}
Probably not the best way but it's working great and avoid the store/update code duplication !
From what I see:
The duplicated part is the first three operations. To avoid writing same code every time you need it, you can create a seperate class for image handling. Let say the class name is Image and the method is createThumbnail. createThumbnail method should get image file as input, do some modifications and return its new name. Create a Libs directory in app directory and put this new Image class there. Whenever you need it just call Image::createThumbnail() and save return value (the new file name) to the database.
You don't have to put your code in either controllers or models. You can create seperate libraries for general purpose task and call them in controllers, models or anywhere you need them.
I hope this helps.
I would fire an event from the controller. Many ways to skin a cat.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community