-
-
Save beberlei/978346 to your computer and use it in GitHub Desktop.
<?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()); | |
} | |
} |
<?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 | |
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); | |
} | |
} |
could you show me the template TWIG when you implements this form upload ?
I really really dont understand what this gist has anything to do with uploading a file in symfony?!?!
Why do I need an entity to upload a file in symfony?
The author definitively didnt understand symfony OR he only follows blindly some examples which he clearly doesnt grasp.
Good job! Keep up the noob work!
The entity is obviously needed to store/persist a reference of the uploaded asset. How else will you access the uploaded file in your code? If you do see another/better way, kindly post it instead of criticizing the author.
P.s. I needed to integrate symfony with a JS library to generate thumbnails of the uploaded images. This article helped me and might help some of you too! :)
The only problem i've had with this approach: defining different folders for each bundle.
Multiple bundles are always loaded so you can't define a variable upload directory for each bundle, the directory will always be overwritten by the last bundle loaded.