You've provided very little code as to how you've followed the file upload feature with Doctrine which would be helpful because there are a dozen ways to approach how the file naming convention is performed, plus you haven't really even shown your own attempt at modifying the entity you're working with the handle multiple file uploading, but I'll give this a shot for you. This is assuming you've followed all of the instructions to the very end.
When you followed the instructions, you probably created a setFile
function as something like:
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
but of course, you are submitting an array of UploadedFile
objects to the setFile
function which doesn't match the UploadedFile
argument that it needs. You also are only storing a single string for the path, so you have to fix that too.
So first you should change your $path
variable type from a string
to some type of array. Assuming you don't need much data associated with each file and the filenames will have no commas in them ever, let's just stick with a simple_array
:
/**
* @ORM\Column(name="paths", type="simple_array")
*/
private $paths = array();
And now you need an array declared for the file
attribute:
/**
* @Assert\File(maxSize="60000000")
*/
private $files = array();
Now you have to change your setFile
function to handle the array input (let's rename to setFiles
for consistency):
public function setFiles($files)
{
$this->files = $files;
// In this scenario, we'll delete the old batch of uploads, so store it in $temp
if (!empty($this->paths)) {
$this->temp = $this->getAbsolutePaths();
}
$this->paths = array();
}
And getFiles
:
public function getFiles()
{
return $this->files;
}
Now your new upload()
function:
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (empty($this->files)) {
return;
}
// Now we have to iterate through each file object
foreach ($this->getFiles() as $file) {
// Change $tempPath to whatever random filename strategy you use
$tempPath = sha1(uniqid(mt_rand(), true)) . '.' . $file->guessExtension();
$file->move(
$this->getUploadRootDir(),
$tempPath
);
// Now add it to the paths array
$this->paths[] = $tempPath;
}
// Need to delete all of the old files
foreach ($this->temp as $del) {
if (is_file($del)) {
unlink($del);
}
}
// Reset the $files var
$files = array();
}
and then for deletions, remove all files entirely:
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
foreach ($this->getAbsolutePaths() as $path) {
if (is_file($path)) {
unlink($path);
}
}
}
For when you're working with the object, you're now handling an array of paths, so you have to update your web and absolute path functions as well:
public function getAbsolutePaths()
{
$out = array();
foreach ($this->getPaths() as $path) {
$out[] = $this->getUploadRootDir().'/'.$this->path;
}
return $out;
}
public function getWebPath()
{
$out = array();
foreach ($this->getPaths() as $path) {
$out[] = '/' . $this->getUploadDir() . '/' . $this->path;
}
}
and voila... once you update your builder to go to files
instead of file
, it should be able to handle the multiple file uploads correctly. Even though the above code is all untested, this should give you plenty to work with.