<?php
class UploadFileMover
{
public function moveUploadedFile(UploadedFile $file, $uploadBasePath)
{
$originalName = $file->getOriginalName();
// use filemtime() to have a more determenistic way to determine the subpath, otherwise its hard to test.
$relativePath = date('Y-m', filemtime($this->file->getPath()));
$targetFileName = $relativePath . DIRECTORY_SEPARATOR . $originalName;
$targetFilePath = $uploadBasePath . DIRECTORY_SEPARATOR . $targetFileName;
$ext = $this->file->getExtension();
$i = 1;
while (file_exists($targetFilePath) && md5_file($file->getPath()) != md5_file($targetFilePath)) {
if ($ext) {
$prev = $i==1 ? "" : $i;
$targetFilePath = $targetFilePath . str_replace($prev . $ext, $i++ . $ext, $targetFilePath);
} else {
$targetFilePath = $targetFilePath . $i++;
}
}
$targetDir = $uploadBasePath . DIRECTORY_SEPARATOR . $relativePath;
if (!is_dir($targetDir)) {
$ret = mkdir($targetDir, umask(), true);
if (!$ret) {
throw new \RuntimeException("Could not create target directory to move temporary file into.");
}
}
$file->move($targetDir, basename($targetFilePath));
return str_replace($uploadBasePath . DIRECTORY_SEPARATOR, "", $targetFilePath);
}
}
<?php
class DocumentController extends Controller
{
public function formAction()
{
$document = new Document();
$form = $this->container->get('form.factory')->create(new DocumentType(), $document);
$request = $this->container->get('request');
if ($request->getMethod() == 'POST') {
if ($form->isValid()) {
$document->processFile();
}
}
}
}
<?php
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @Entity
*/
class Document
{
/** @var File - not a persistent field! */
private $file;
/** @var string
* @Column(type="string")
*/
private $filePersistencePath;
/** @var string */
protected static $uploadDirectory = null;
static public function setUploadDirectory($dir)
{
self::$uploadDirectory = $dir;
}
static public function getUploadDirectory()
{
if (self::$uploadDirectory === null) {
throw new \RuntimeException("Trying to access upload directory for profile files");
}
return self::$uploadDirectory;
}
/**
* Assumes 'type' => 'file'
*/
public function setFile(File $file)
{
$this->file = $file;
}
public function getFile()
{
return new File(self::getUploadDirectory() . "/" . $this->filePersistencePath);
}
public function getFilePersistencePath()
{
return $this->filePersistencePath;
}
public function processFile()
{
if (! ($this->file instanceof UploadedFile) ) {
return false;
}
$uploadFileMover = new UploadFileMover();
$this->filePersistencePath = $uploadFileMover->moveUploadedFile($this->file, self::getUploadedDirectory());
}
}