Created
June 24, 2013 16:06
-
-
Save antonmedv/5851204 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* (c) Anton Medvedev <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
use Symfony\Component\Validator\Constraints as Assert; | |
/** | |
* @ORM\Entity | |
*/ | |
class Avatar extends File | |
{ | |
/** | |
* @Assert\File(maxSize="2M", mimeTypes={"image/png", "image/jpeg"}, groups={"avatar"}) | |
*/ | |
protected $file; | |
public function __toString() | |
{ | |
return (string)$this->getUrl(); | |
} | |
public function generatePath() | |
{ | |
$filename = sha1(uniqid(mt_rand(), true) . $this->getFile()->getClientOriginalName()); | |
$prefix = substr($filename, 0, 2) . '/' . substr($filename, 2, 2) . '/'; | |
return $prefix . $filename . '.' . $this->getFile()->guessExtension(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// ... | |
// Then bootstraping. | |
File::setUploadPath(__DIR__ . '/upload'); | |
// ... | |
// Then request is ready or you know base path url. | |
public function onKernelRequest(GetResponseEvent $event) | |
{ | |
$request = $event->getRequest(); | |
File::setBaseUrl($request->getBasePath() . '/upload'); | |
} | |
// ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* (c) Anton Medvedev <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
use Symfony\Component\Validator\Constraints as Assert; | |
use Symfony\Component\HttpFoundation\File\UploadedFile; | |
/** | |
* @ORM\Entity() | |
* @ORM\InheritanceType("SINGLE_TABLE") | |
* @ORM\DiscriminatorColumn(name="type", type="string") | |
* @ORM\DiscriminatorMap({"file" = "Entity\File", "avatar" = "Entity\Avatar"}) | |
* @ORM\Table("Uploads") | |
* @ORM\HasLifecycleCallbacks | |
*/ | |
class File | |
{ | |
/** | |
* @ORM\Id | |
* @ORM\Column(type="integer") | |
* @ORM\GeneratedValue | |
*/ | |
protected $id; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
protected $path; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
protected $filename; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
protected $mimetype; | |
/** | |
* @ORM\Column(type="string", length=255, nullable=true) | |
*/ | |
protected $extension; | |
/** | |
* @Assert\File(maxSize="2M") | |
* @var UploadedFile | |
*/ | |
protected $file; | |
/** | |
* Temporary file path for deleting later. | |
* @var string | |
*/ | |
private $deleteFilePath; | |
/** | |
* Server path to upload directory. | |
* @var string | |
*/ | |
static private $uploadPath; | |
/** | |
* Web url to upload directory. | |
* @var string | |
*/ | |
static private $baseUrl; | |
public function getAbsolutePath() | |
{ | |
return null === $this->path | |
? null | |
: self::getUploadPath() . '/' . $this->path; | |
} | |
public function getUrl() | |
{ | |
return null === $this->path | |
? null | |
: self::getBaseUrl() . '/' . $this->path; | |
} | |
/** | |
* Sets file. | |
* | |
* @param UploadedFile $file | |
*/ | |
public function setFile(UploadedFile $file = null) | |
{ | |
$this->file = $file; | |
// Change path member for Unit of Work of Doctrine. | |
if (isset($this->path)) { | |
$this->deleteFilePath = $this->getAbsolutePath(); | |
$this->path = null; | |
} else { | |
$this->path = 'initial'; | |
} | |
} | |
/** | |
* @ORM\PrePersist() | |
* @ORM\PreUpdate() | |
*/ | |
public function preUpload() | |
{ | |
if (null !== $this->getFile()) { | |
$this->path = $this->generatePath(); | |
$this->filename = $this->getFile()->getClientOriginalName(); | |
$this->extension = $this->getFile()->getClientOriginalExtension(); | |
$this->mimetype = $this->getFile()->getClientMimeType(); | |
} | |
} | |
public function generatePath() | |
{ | |
$filename = sha1(uniqid(mt_rand(), true) . $this->getFile()->getClientOriginalName()); | |
$prefix = substr($filename, 0, 2) . '/' . substr($filename, 2, 2) . '/'; | |
return $prefix . $filename . '.file'; | |
} | |
/** | |
* @ORM\PostPersist() | |
* @ORM\PostUpdate() | |
*/ | |
public function upload() | |
{ | |
if (null === $this->getFile()) { | |
return; | |
} | |
$explodedPath = explode('/', $this->path); | |
$filename = array_pop($explodedPath); | |
$directory = implode('/', $explodedPath); | |
$this->getFile()->move( | |
$this->getUploadPath() . '/' . $directory, | |
$filename | |
); | |
// check if we have an old image | |
if (isset($this->deleteFilePath)) { | |
if (is_file($this->deleteFilePath)) { | |
unlink($this->deleteFilePath); | |
} | |
$this->deleteFilePath = null; | |
} | |
$this->file = null; | |
} | |
/** | |
* @ORM\PostRemove() | |
*/ | |
public function removeUpload() | |
{ | |
if ($file = $this->getAbsolutePath()) { | |
unlink($file); | |
} | |
} | |
/** | |
* @return UploadedFile | |
*/ | |
public function getFile() | |
{ | |
return $this->file; | |
} | |
/** | |
* @param string $directoryPath | |
*/ | |
public static function setUploadPath($directoryPath) | |
{ | |
self::$uploadPath = $directoryPath; | |
} | |
/** | |
* @return string | |
*/ | |
public static function getUploadPath() | |
{ | |
if(empty(self::$uploadPath)) { | |
throw new \RuntimeException('Upload path does not specified for File class.'); | |
} | |
return self::$uploadPath; | |
} | |
/** | |
* @param string $directoryUrl | |
*/ | |
public static function setBaseUrl($directoryUrl) | |
{ | |
self::$baseUrl = $directoryUrl; | |
} | |
/** | |
* @return string | |
*/ | |
public static function getBaseUrl() | |
{ | |
if(empty(self::$baseUrl)) { | |
throw new \RuntimeException('Base url does not specified for File class.'); | |
} | |
return self::$baseUrl; | |
} | |
public function __toString() | |
{ | |
return (string)$this->filename; | |
} | |
/** | |
* This method need for properly work of Security Component. | |
* Serialization of UploadedFile class is not allowed. | |
* | |
* @return array | |
*/ | |
public function __sleep() | |
{ | |
return array('id', 'path', 'filename', 'mimetype', 'extension'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment