Bug image field, store in fake field (store as base64, not path)
See original GitHub issueHello,
I try to store the path of an image in a fake field. And it converts it to “base64”, it’s a problem. It works when I specify a field other than “extras” and I create my mutator.
As I have several images on my pages (I use PageManager for simple pages). I need to store a different number on each page, which is why I would like a “fake field” solution, it would keep it flexible.
I try to follow the solution given here by @tabacitu Laravel-Backpack/CRUD#400.
Whatever I do, if I try to store an image in “extras”, it converts it to base64 and that bug and even with the following code
public function setImageAttribute($value, $attribute_name = 'image')
{
$disk = "public_folder";
$destination_path = "uploads/folder_1/subfolder_3";
// if the image was erased
if ($value==null) {
// delete the image from disk
\Storage::disk($disk)->delete($this->image);
// set null in the database column
$this->attributes[$attribute_name] = null;
}
// if a base64 was sent, store it in the db
if (starts_with($value, 'data:image'))
{
// 0. Make the image
$image = \Image::make($value);
// 1. Generate a filename.
$filename = md5($value.time()).'.jpg';
// 2. Store the image on disk.
\Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
// 3. Save the path to the database
$this->attributes[$attribute_name] = $destination_path.'/'.$filename;
}
}
I try to have something dynamic, otherwise I could post only one entry per column in the DB.
@tabacitu has given information to try to solve this problem. But I can not create it correctly.
So, is there a way to store multiple images from different fields on the same page in a fake-field?
Thank you
PS : Sorry for my english.
Issue Analytics
- State:
- Created 6 years ago
- Comments:25 (17 by maintainers)
Hi everyone. Allow me to post this to this closed topic. It could be useful to someone.
Looking for a solution to @Jimmylet post I landed here. I finally managed to store image paths into a fake field. It’s not the best solution, as I didn’t rewrite the backpack code to add this functionality, but it works. I’m not sure it’s a backpack bug, but it’s just something the fake fields are not thought for. Nothing mentioned in the documentation though (whether it should work or shouldn’t).
As far as I could guess, the moment in the store call stack where actual values are written into the fake fields is inside some of the backpack structure (Model.php). To modify that behavior I should override quite a lot of files, and I didn’t want to mess them up. Not now. So, why previous comments didn’t work for me: The getters and setters like getSomeFieldAttribute don’t work as we would expect for fake fields. They do work for actual fields in the table. If you try to do setExtrasAttribute and do there the image processing, it also doesn’t work, as the extras field is at the same time a “protected $fake” field and a “protected $appends” field.
So, what I did is to surface to the controller itself and insert the following code into the update and create methods. The code basically checks for fields ending with _image, then stores images to disk, gets their filename, and replaces the fake field data (data:image) with the recently created filename. Volià! Don’t pay attention to the specific code that you won’t need. This code is mostly the part of the setImageAttribute function where images are processed for actual DB fields. The model keeps the getImageAttribute (second part of the code) with the getAttributeValueExtended trick to parse the value to store and read it json_decoded from the fake field.
In the controller:
In the model:
Hope this helps someone!
Thanks a lot for sharing this @brynnb . I’m sure it will help others indeed.
To re-use the Update operation in Backpack 4, take a look at this section in the Update operation docs (or point 6.2 in the upgrade guide). You should be able to do something like this:
(not exact code, just a suggestion)