-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Form file uploads #400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Form file uploads #400
Conversation
// you must throw an exception here if the file cannot be moved | ||
// so that the entity is not persisted to the database | ||
// which the UploadedFile move() method does | ||
$this->file->move($this->getUploadRootDir(), $this->generatePath($this->file)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you have an issue here: you generate the path twice so the file will not use the same path than the persisted one. You should use $this->path
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, you also use only the file name instead of the full path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hehe, I've changed the code just before committing it... without testing it. My bad.
The |
The |
First, let's create a simple Doctrine Entity to work with:: | ||
|
||
use Doctrine\ORM\Mapping as ORM; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you need to add
use Symfony\Component\Validator\Constraints as Assert;
since there's an @Assert in used in line 26
If anyone spots anything else on this, please let me know - I'm merging this now so that it'll be included in the next rendering. |
|
||
protected function getUploadRootDir() | ||
{ | ||
return '/path/to/uploaded/documents'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a hack - how could we have a hard-coded path included like this? I've been doing something similar to this, but have injected this information (which is quite unfortunate).
Overall. I think this highlights the issue with trying to handle all of this from within an entity. It seems like it might be more appropriate to hand all of this off to some other service - which could handle the unique filename stuff, the moving of the files, setting of the path. In theory - though I don't see exactly how - that service could listen on Doctrine and respond to entities that implement a certain interface (with methods that give information on how to get file information).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way we've been dealing with this is by using a service to handle it, as you say. It means however, that we've set our Entity to explicit flush type so that EM flushes wont touch the entity unless our service wants them to.
No doctrine listener, just a coding standard that everything must use its manager service instead of raw doctrine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to draw the line somewhere. This cookbook entry is just a starting point for you own implementation. I've tried to find a good balance between correctness and simplicity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the cookbook entry is very good - it builds the details nicely.
I just think that the cookbook entry highlights a missing feature - be it in a bundle or in core - which removes the need for the boilerplate code and replaces it with some simple configuration (choose target directory, choose filename generation method, specify "file" field, specify "path" field...).
It's not really a concern for the framework, but from a practical standpoint, there's also the issue of managing exactly which files you have where (e.g. Product
photo is in /uploads/products, Blog
photos in /uploads/blog) and making that information available while handling file uploads and in the view, where you're creating paths to the files.
So, I'm just thinking out loud :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weaverryan Making it configurable will require using the lifecycle event instead of the lifecycle callback. Once the logic is moved to a listener, the service can also be used in the view.
And for the use of different directories, just add some logic in the getUploadRootDir
method, based on another property oof the entity.
Guys, I may be wrong but, why you don't attach 2 listeners on I would add
+1 It's really sad that we can't can't find a way to use |
@tristanbes which events are PreUpload and Upload ? |
@stof they are functions on which only This reflexions leads to what @poussain told : if only the virtual field is changed, none of the LifeCycle Callbacks are called UPDATE: after testing, i'm not able to reproduce the virtual field thing with lifeCycle Callbacks that poussain reported. I changed only the avatar image among untouched mapped fields and it called the |
I know that it is old discussion, but i`m writing here for confirmation before opening new issue.
Can anybody confirm? |
File uploads documentation is here: symfony/symfony-docs#400
File uploads documentation is here: symfony/symfony-docs#400
I've updated the file type reference section to reflect the latest changes of the code and added a new entry in the cookbook to explain how to manage file uploads with Doctrine entities. I'm not really satisfied with the text as it makes you think that this is really complex but in fact, it's not. Hopefully, the magical @weaverryan will fix that.