How come filename include the directory

Hi why does the file name of a file upload include the directory name ? I have this in my form
Forms\Components\FileUpload::make('filename')
->required()
->getUploadedFileNameForStorageUsing(function (TemporaryUploadedFile $file): string {
return Str::orderedUuid() . '.docx';
})->disk('public')
->directory('templates'),
Forms\Components\FileUpload::make('filename')
->required()
->getUploadedFileNameForStorageUsing(function (TemporaryUploadedFile $file): string {
return Str::orderedUuid() . '.docx';
})->disk('public')
->directory('templates'),
after file upload the filename is something like this.
templates/993ea9ce-598f-4f6c-ae04-645f3321c7b5.docx
templates/993ea9ce-598f-4f6c-ae04-645f3321c7b5.docx
47 Replies
Dennis Koch
Dennis Koch2y ago
Because in Laravel the disk is the root and paths and URLs are resolved from there
rabol
rabolOP2y ago
yes, but that does not explain why Filament add the ¨template/' to my file name return Storage::disk('public')->download('/templates/'.$userDocTemplateSample->filename); will fail because the name includes '/template' twice I use a callback to specify the filename the files are stored in the correct place
Dennis Koch
Dennis Koch2y ago
Yes but why do you even add that prefix?
rabol
rabolOP2y ago
I don't add prefix I create my own name, put the file in a specific folder and store the data getUploadedFileNameForStorageUsing() is used to specify your own name even if I just go with the 'default' name, the directory is prepended to the final filename if there is another way to control the location and filename, then please let me know
rabol
rabolOP2y ago
https://filamentphp.com/docs/2.x/forms/fields#file-upload "To change the disk and directory that files are saved in, and their visibility, use the disk(), directory() and visibility methods:"
Filament
Fields - Form Builder - Filament
The elegant TALL stack form builder for Laravel artisans.
Dennis Koch
Dennis Koch2y ago
I mean this one: return Storage::disk('public')->download('/templates/'. It makes sense to save the full path from the disk root. E.g. if you decide to store files in a different folder. Or if your folders are dynamic
rabol
rabolOP2y ago
because the file is in the /templates directory but it does not store the full path
Dennis Koch
Dennis Koch2y ago
Yes but that information is already saved? I thought that's your issue? That it saves the full path from the storage root I don't understand why this is an issue?
rabol
rabolOP2y ago
the issue is that when using the ->directory() it then prepend that to the filename, and when I display the file name I don want to see that and it's not what the documentation say
Dennis Koch
Dennis Koch2y ago
Where does the documentation say something different? This?
"To change the disk and directory that files are saved in, and their visibility, use the disk(), directory() and visibility methods:"
It saves in the right directory, right?
when I display the file name I don want to see that
But why? Just because?!
rabol
rabolOP2y ago
To change the disk and directory that files are saved in, and their visibility, use the disk(), directory() and visibility methods: that is what the doc say
Dennis Koch
Dennis Koch2y ago
Yes? And what's wrong about that?
rabol
rabolOP2y ago
not that the file name will contain the directory the doc is fine, exactly what I want, but as I specifically assign my own name, I want my own name
Dennis Koch
Dennis Koch2y ago
If you absolutely want to change that I think you can overwrite the storage logic and trim the directory from the path via saveUploadedFileUsing()
rabol
rabolOP2y ago
but why? The doc say to use the disk() and the directory() to specify the location, the getUploadedFileNameForStorageUsing() is used to specify my own name instead of the one by Livewire. all of this is what I would like, but.... Filament add the directory to the filename
Dennis Koch
Dennis Koch2y ago
but why?
I think I already commented on that question: Because Laravel Storage works that way Storage::path($filename) works out of the box without putting together filepaths.
The doc say to use the disk() and the directory() to specify the location
Yes. And that's working.
getUploadedFileNameForStorageUsing() is used to specify my own name instead of the one by Livewire.
And that's also working. It's about the fileName not filePath
rabol
rabolOP2y ago
from the livewire doc: https://laravel-livewire.com/docs/2.x/file-uploads those filenames does not change, only the location
Livewire
File Uploads | Livewire
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
Dennis Koch
Dennis Koch2y ago
If the prefix bugs you and you want to prefix that stuff overwrite the saveUploadedFileUsing()
rabol
rabolOP2y ago
yes, and I specify a filename, but Filament change that
awcodes
awcodes2y ago
where are you trying to display the filename?
Dennis Koch
Dennis Koch2y ago
Since you are pointing to the Livewire docs. Try this $this->photo->storeAs('photos', 'avatar'); and see what it returns: photos/avatar So Filament does the same thing as Laravel and Livewire.
awcodes
awcodes2y ago
Filament stores the disk name as part of the path since it's a text string to the location of the file inside for the specified disk. If you just want to display the filename then it's as simple as formatting the state with basename('/templates/myfile.jpg')
rabol
rabolOP2y ago
yes, that is because that is the path to the file, it does not change the filename
Dennis Koch
Dennis Koch2y ago
But it's the same with FileUpload? templates/993ea9ce-598f-4f6c-ae04-645f3321c7b5.docx is the path to the file
awcodes
awcodes2y ago
The FileUpload component has to store the directory and the filename as a 'path' in the database, because without it there is no way to retrieve the directory name back out of the database. ie. if 'myfile.jpg' was stored in the db you would loose the directory name when retrieving the data. again if you just need the 'file name' you can use basename() to get it.
Dennis Koch
Dennis Koch2y ago
@steen.rabol Is the decision behind this clear now? Do you need any other help with this?
rabol
rabolOP2y ago
if it's because you want to close it, then please close, I still don't agree due to the fact that I specifically create my own name, I would agree if I used all the default settings But, please go ahead and close
Dennis Koch
Dennis Koch2y ago
No it's not because I want to close it.
I still don't agree due to the fact that I specifically create my own name
Again, there is a a difference between filename and filepath. That method is meant to override the filename. We don't have one for overwriting the filepath.
rabol
rabolOP2y ago
yes you have ->directory()
Dennis Koch
Dennis Koch2y ago
But you can make it work like you want it with the function I told you
rabol
rabolOP2y ago
yes, I can make it work
Dennis Koch
Dennis Koch2y ago
I mean "overwriting the full file path for storaging in db"
Frédéric
Frédéric9mo ago
Hey, sorry to re-open this thread, but i'm facing the same issu. Generaly I like save only the filename in database in case the project changes. If I want to reorder Storage Directory, i juste change my method picture_path. Why don't you create an option 'saveOnlyFilename" and use / add the directory() method where it's necessary ? For the moment i keep the filepath, but i prefere if i can store only the filename. Thx in advance Hello, little up ! 😄
altemp.
altemp.9mo ago
The same thing happens to me, I want to save only the file name in my database, but I want it to be saved within a specific directory, disk "private", directory "invoices". I can change to force not including the directory in the database, but if I do this, it doesn't save in the target folder, and vice versa, I can save it in the target folder, but in this case, it's impossible to remove the name of that folder from the database... Any solution/suggestion?
Frédéric
Frédéric9mo ago
Hello, Thx for your post ! Anybody have a solution ? 😮 Hello, daily Up ^^'
Dennis Koch
Dennis Koch9mo ago
I did suggest using saveUploadedFileUsing() for storing and disk() for setting a different disk.
Frédéric
Frédéric9mo ago
Thx for your anwers but i don't know how to use it, i try to found it on the documentation without success 😮 FileUpload::make('carrousel') ->image() ->imagePreviewHeight(160) ->columnSpanFull() ->multiple() ->preserveFilenames() ->saveUploadedFileUsing(?????) ->disk(fn(?Model $record) => config('models.product.picture_base_url') . $record->slug) ->appendFiles(false) ->reorderable()
Dennis Koch
Dennis Koch9mo ago
It's an internal method. Check the FileUpload code for the default implementation
Frédéric
Frédéric9mo ago
here ? Apparently i do not want a default implementation because I would like save only the filename and not the filepath ^^'
Dennis Koch
Dennis Koch9mo ago
I said Code! Not documentation Sure. But the default implementation would be a good starting point. The rest is on you. There's no out-of-the-box feature.
Frédéric
Frédéric9mo ago
you speak abount this ? $this->saveUploadedFileUsing(static function (BaseFileUpload $component, TemporaryUploadedFile $file): ?string { try { if (! $file->exists()) { return null; } } catch (UnableToCheckFileExistence $exception) { return null; } if ( $component->shouldMoveFiles() && ($component->getDiskName() == (fn (): string => $this->disk)->call($file)) ) { $newPath = trim($component->getDirectory() . '/' . $component->getUploadedFileNameForStorage($file), '/'); $component->getDisk()->move((fn (): string => $this->path)->call($file), $newPath); return $newPath; } $storeMethod = $component->getVisibility() === 'public' ? 'storePubliclyAs' : 'storeAs'; return $file->{$storeMethod}( $component->getDirectory(), $component->getUploadedFileNameForStorage($file), $component->getDiskName(), ); }); Thx to your help, juste a single question, if during the application's life I decide to change the structure file, how can I manage easily if the filepath is fully in the db ? with only the filename in the database, i juste need to change my config file, it's seem to be a good practice.
Dennis Koch
Dennis Koch9mo ago
Yes
juste a single question, if during the application's life I decide to change the structure file, how can I manage easily if the filepath is fully in the db ?
You'd need to update the DB data.
with only the filename in the database, i juste need to change my config file, it's seem to be a good practice.
Well, maybe that's why it's the default 😉
Frédéric
Frédéric9mo ago
you confuse me ^^' I install filament on two applications,the first one I let the default : FileUpload::make('carrousel') ->image() ->getUploadedFileNameForStorageUsing(fn($get) => CarHelper::defineImageName($get)) ->directory(fn($get) => 'images/cars/'. $get('plate')) ->imagePreviewHeight(160) ->columnSpanFull() ->multiple() ->appendFiles(false) ->reorderable() it register: ["images/cars/TJ182MI/car-1-1.webp","images/cars/TJ182MI/car-1-2.webp","images/cars/TJ182MI/car-1-3.webp","images/cars/TJ182MI/car-1-4.webp"]
Well, maybe that's why it's the default 😉
So I don't understand this ^^'
You'd need to update the DB data.
With a big amount of datas I prefer juste change the method in my model who generate the path !
Dennis Koch
Dennis Koch9mo ago
With a big amount of datas I prefer juste change the method in my model who generate the path
So what is the current issue? Shouldn't that be the default behaviour of FileUpload?
Frédéric
Frédéric9mo ago
I don't know if it should be the default behaviour but we should can choose to store or the filename or filepath. I'm confused, the filament's default behaviour is too store the filepath ? right ?
Amitoj
Amitoj5mo ago
I have same concern, I only want to save filename in the database regardless in which directory the file goes. Do you think it make sense to use laravel's model accessor to change the value when saving and accessing:
protected function icon(): Attribute{
return Attribute::make(
get: fn(string $value) => $value ? storage('company.icon.path') . '/' . $value : null,
set: fn($value) => $value ? basename($value) : null
);
}
protected function icon(): Attribute{
return Attribute::make(
get: fn(string $value) => $value ? storage('company.icon.path') . '/' . $value : null,
set: fn($value) => $value ? basename($value) : null
);
}
This seems to be working, but can someone confirm if it is reliable for filament or if there is better approach?
Want results from more Discord servers?
Add your server