Fileupload not saving to DB

Hi, I've got what I thought would be a simple fileupload component:
FileUpload::make('image')
->directory('blog-attachments')
->visibility('public')
->preserveFilenames()
->storeFileNamesIn('image')
->imageEditor()
->imageEditorAspectRatios([
null,
'16:9',
'4:3',
'1:1',
])
->moveFiles()
->columnSpan(2),
FileUpload::make('image')
->directory('blog-attachments')
->visibility('public')
->preserveFilenames()
->storeFileNamesIn('image')
->imageEditor()
->imageEditorAspectRatios([
null,
'16:9',
'4:3',
'1:1',
])
->moveFiles()
->columnSpan(2),
The DB column is called "image", it's a varchar(255). It's listed in the $fillable property of the model. The image file is uploaded to storage/app/livewire-tmp/ successfully. One point, it's saved in the format "4UwLQXBBr7UQzl9KU0PPfcFCPwM0AA-metaYXNhbmEtYm9hcmQucG5n-.png", rather then the original filenames, which I thought preserveFilenames() would prevent. The directory 'blog-attachments' is never created. Everything is good in the UI - no errors in the browser nor console. But when I save the resource, the image field in the DB is populated with "[]" If I change the component config to the bare minimum (FileUpload::make('image')), then the [] is replaced with a null. Any ideas?
Solution:
I've removed stancl/tenancy. Image upload now working other than the URL being incorrect, but that's a minor issue. I started using stancl because I did want tenancy, but not the one user:many tenants model that Filament has. But you're right - there are easier ways than the formal packages 🙂
Jump to solution
30 Replies
awcodes
awcodes6mo ago
storeFileNamesIn() needs to be a separate column on the db and can’t be named the same as the image field. Essentially it’s overriding your ‘image’ field. You also don’t need it at all if you are preserving file names.
_andypeacock
_andypeacock5mo ago
Ah, thanks. I'll have a play with it again tonight when I log on. Appreciate your help.
_andypeacock
_andypeacock5mo ago
mm. That didn't work unfortunately. I've trimmed the field right back to:
FileUpload::make('image'),
FileUpload::make('image'),
And added a beforeSave function log $this->record and $this->data in the EditRecord.php page Record:
{
"id": 1,
"user_id": 1,
"tenant_id": 1,
"type": "post",
"title": "Test post 7",
"excerpt": "Odit ipsam beatae consequatur laudantium amet est. Quia placeat id aliquam ut ut labore velit. Error sint nisi dolorum et dolores quas. Quos voluptas porro est.",
"content": "<p>Ad quis reiciendis sed et. Sunt aut voluptates quis totam eum laudantium. Ut ullam nihil labore repudiandae. Laborum accusamus optio quasi non aut.</p>",
"slug": "test-post-7",
"is_slug_manual_override": false,
"image": null,
"status": "published",
"created_at": "2024-01-03T21:36:28.000000Z",
"updated_at": "2024-01-03T21:52:52.000000Z",
"published_at": "2024-01-03 21:36:28",
"deleted_at": null
}
{
"id": 1,
"user_id": 1,
"tenant_id": 1,
"type": "post",
"title": "Test post 7",
"excerpt": "Odit ipsam beatae consequatur laudantium amet est. Quia placeat id aliquam ut ut labore velit. Error sint nisi dolorum et dolores quas. Quos voluptas porro est.",
"content": "<p>Ad quis reiciendis sed et. Sunt aut voluptates quis totam eum laudantium. Ut ullam nihil labore repudiandae. Laborum accusamus optio quasi non aut.</p>",
"slug": "test-post-7",
"is_slug_manual_override": false,
"image": null,
"status": "published",
"created_at": "2024-01-03T21:36:28.000000Z",
"updated_at": "2024-01-03T21:52:52.000000Z",
"published_at": "2024-01-03 21:36:28",
"deleted_at": null
}
No description
_andypeacock
_andypeacock5mo ago
Data:
{
"id": 1,
"user_id": 1,
"tenant_id": 1,
"type": "post",
"title": "Test post 8",
"excerpt": "Odit ipsam beatae consequatur laudantium amet est. Quia placeat id aliquam ut ut labore velit. Error sint nisi dolorum et dolores quas. Quos voluptas porro est.",
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "start",
"class": false
},
"content": [
{
"type": "text",
"text": "Ad quis reiciendis sed et. Sunt aut voluptates quis totam eum laudantium. Ut ullam nihil labore repudiandae. Laborum accusamus optio quasi non aut."
}
]
}
]
},
"slug": "test-post-8",
"is_slug_manual_override": false,
"image": [

],
"status": "published",
"created_at": "2024-01-03T21:36:28.000000Z",
"updated_at": "2024-01-03T21:52:52.000000Z",
"published_at": "2024-01-03 21:36:28",
"deleted_at": null,
"categories": [

]
}
{
"id": 1,
"user_id": 1,
"tenant_id": 1,
"type": "post",
"title": "Test post 8",
"excerpt": "Odit ipsam beatae consequatur laudantium amet est. Quia placeat id aliquam ut ut labore velit. Error sint nisi dolorum et dolores quas. Quos voluptas porro est.",
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "start",
"class": false
},
"content": [
{
"type": "text",
"text": "Ad quis reiciendis sed et. Sunt aut voluptates quis totam eum laudantium. Ut ullam nihil labore repudiandae. Laborum accusamus optio quasi non aut."
}
]
}
]
},
"slug": "test-post-8",
"is_slug_manual_override": false,
"image": [

],
"status": "published",
"created_at": "2024-01-03T21:36:28.000000Z",
"updated_at": "2024-01-03T21:52:52.000000Z",
"published_at": "2024-01-03 21:36:28",
"deleted_at": null,
"categories": [

]
}
As you can see image is either null or empty array. Yet the image seems to be uploaded correctly by the file field as per previous screenshot During that initial upload, the file is saved to /storage/app/livewire-tmp And I've checked the $fillable array, and it looks good:
protected $fillable = [
'title',
'excerpt',
'content',
'image',
'status',
'type',
'image',
'published_at',
'slug',
'is_slug_manual_override',
'tenant_id',
'user_id'
];
protected $fillable = [
'title',
'excerpt',
'content',
'image',
'status',
'type',
'image',
'published_at',
'slug',
'is_slug_manual_override',
'tenant_id',
'user_id'
];
I'm using stancl/tenancy, and the middleware is applied to livewire:
Livewire::setUpdateRoute(function ($handle) {
logger("Livewire middleware applied");
return Route::post('/livewire/update', $handle)
->middleware(
'web',
'universal',
InitializeTenancyBySubdomain::class, // or whatever tenancy middleware you use
);
});
Livewire::setUpdateRoute(function ($handle) {
logger("Livewire middleware applied");
return Route::post('/livewire/update', $handle)
->middleware(
'web',
'universal',
InitializeTenancyBySubdomain::class, // or whatever tenancy middleware you use
);
});
The "Livewire middleware applied" is logged, so it's running. And I've run "php artisan storage:link" just to be sure, even though I'm pretty confident I'd run that a long long time ago. No change. Hmm. The SQL that is run when the modal is saved, includes the other fields but not the image one. I'm assuming that's an issue... I've tried changing the fieldname to "featured_image" in the DB, $fillable, and filament field, in case plain "image" was causing an issue. No change.
awcodes
awcodes5mo ago
Definitely odd. Probably doesn’t matter but you do have image in your fillable array twice. Image isn’t a relationship by any chance is it?
_andypeacock
_andypeacock5mo ago
ah, missed that image the first time. No, not a relationship, just a text mysql field Ah, this is strange, if I add ->storeFiles(false), then the featured_image field is populated with /tmp/phpIV7B8c
awcodes
awcodes5mo ago
That doesn’t make any sense at all.
_andypeacock
_andypeacock5mo ago
Yeah, it's thrown me completely as well. I'm currently dd()ing my way through the core BaseFileUpload to see what's going on But I appreciate your help anyway My gut is saying it's something to do with the stancl/tenancy package...
_andypeacock
_andypeacock5mo ago
Getting there. This check fails:
No description
awcodes
awcodes5mo ago
But the file should exist because livewire side loads it.
_andypeacock
_andypeacock5mo ago
It does - wrong location
awcodes
awcodes5mo ago
That’s the whole point of the tmp directory.
_andypeacock
_andypeacock5mo ago
Livewire uploads to storage/app/livewire-tmp/xxxx, but the $file is looking at /tmp/yyyyy
awcodes
awcodes5mo ago
Yea, something is definitely messing with the config then. Could always change the tmp directory in the livewire config. If you can’t track it down.
_andypeacock
_andypeacock5mo ago
Just tried that. but the filenames aren't the same. Livewire saves to a long filename like 0HDMiiX6YrPv4aflaZpG3Cy675FOpG-metaY29taW5nLXNvb24uanBn-.jpg , but the filament copmonent is looking for something like php3YpkBL But it's very late now and I need some sleep or I'll be Mr Grumpy tomorrow, so I'll park it and come back tomorrow night. Really appreicate your help on this, @awcodes
awcodes
awcodes5mo ago
No worries. Get some rest.
_andypeacock
_andypeacock5mo ago
No idea. Really wierd. If I just use a fresh livewire component on a separate route, it works fine. The filament demo runs fine so it's nothing to do with permissions or wierd stuff on my WSL OS (at least I don't think so). I've added loads of logging, and livewire definitely writes to the location it's supposed to, eg storage/app/livewire-tmp/. I just can't work out where filament is getting the "/tmp" from, nor where the livewire location should be. The call to the /livewire/upload-file route returns {"paths":["/XSo3cwxY3ZthHmSJEOHNxeE0wT33xn-metac2NyZWVuc2hvdC5wbmc=-.png"]} But in the BaseFileUpload.php saveUploadedFiles() function, state is:
"state": {
"c2af0a09-11d6-4c2e-8045-073afd41e3d9": "/tmp/phpuTAtBx"
}
"state": {
"c2af0a09-11d6-4c2e-8045-073afd41e3d9": "/tmp/phpuTAtBx"
}
awcodes
awcodes5mo ago
Run a find in your app and possibly the vendor directory for ‘/tmp’. Something is overriding it.
_andypeacock
_andypeacock5mo ago
Nothing that I can see. I'm still thinking this is some wierd tenancy/livewire/filament bogeyman. Might get rid of tenancy and go back to the "simple tenancy" described in the docs. There's only one thing i wanted to use the stancl package for, and if it's going to cause problems like this, I'll find a workearound
awcodes
awcodes5mo ago
Maybe. Real question is do you actually need the complication of tenancy? Lol.
Solution
_andypeacock
_andypeacock5mo ago
I've removed stancl/tenancy. Image upload now working other than the URL being incorrect, but that's a minor issue. I started using stancl because I did want tenancy, but not the one user:many tenants model that Filament has. But you're right - there are easier ways than the formal packages 🙂
_andypeacock
_andypeacock5mo ago
So right now I've off to re-write all the tenant-based functionality. See you some time next month 🙂 Again, appreciate your help on this.
BKF Dev
BKF Dev5mo ago
Hello, I want to apply multi tenancy using this package stancl, I wonder if it's possible and easy, I'm using curator for media,
awcodes
awcodes5mo ago
Curator is tenant aware by default. Meaning media is scoped to the tenant by default.
BKF Dev
BKF Dev5mo ago
Thanks @awcodes for reply, Actually, I'm getting this error on file upload : Unable to retrieve the file_size for file at location: livewire-tmp/zuLeCTvelTjdLbaP4YMKcJFcJ79D6x-metaYm5yMi5wbmc=-.png. the file is temporarily uploaded to default path : storage/app/livewire-tmp, I've installed stancl tenancy package Nevermind, I fixed it 🙂
Harry
Harry5mo ago
@BKF Dev How did you fix it?
BKF Dev
BKF Dev5mo ago
Hi @Harry Just extend the media model and then override two functions, I know it's not a good solution but at least it saves me and let me go ahead,
BKF Dev
BKF Dev5mo ago
No description
No description
Harry
Harry5mo ago
Excellent cheers
BKF Dev
BKF Dev5mo ago
Enjoy 🙂