Skip to content

Instantly share code, notes, and snippets.

@IvanAlekseevichPopov
Last active April 27, 2018 11:49
Show Gist options
  • Save IvanAlekseevichPopov/8951c826a25b2a3b458439615b18bb53 to your computer and use it in GitHub Desktop.
Save IvanAlekseevichPopov/8951c826a25b2a3b458439615b18bb53 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace App\Form\Model;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File;
/**
* AbstractImage.
*/
abstract class AbstractImage
{
public const BASE_PATH = 'static/images';
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false, options={"unsigned": true})
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="extension", type="string", length=5, nullable=false)
*/
protected $extension;
/**
* @var File
*/
protected $file;
/**
* @return null|File
*/
public function getFile(): ?File
{
return $this->file;
}
/**
* @param File $file
*
* @throws \Exception
*
* @return $this
*/
public function setFile(File $file)
{
if (!$file->isReadable()) {
throw new \Exception('file read error');
}
$this->file = $file;
$this->setExtension($this->genExtension($file));
return $this;
}
/**
* @return string
*/
final public function getFilePath()
{
return sprintf('%s/%s', $this->getBasePath(), $this->getFileName());
}
/**
* @return string|null
*/
public function getExtension(): ?string
{
return $this->extension;
}
/**
* @param string $extension
*
* @return $this
*/
public function setExtension(string $extension)
{
$this->extension = $extension;
return $this;
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* Puts file to filesystem.
*
* @param null|string $projectPath
*/
final public function saveFile(?string $projectPath = null)
{
$fs = new FileSystem();
$fs->mkdir($this->getBasePath());
$this->file->move($projectPath.$this->getBasePath(), $this->getFileName());
}
/**
* Removes reference file.
*
* @param null|string $projectPath
*/
final public function removeFile(?string $projectPath = null)
{
$fs = new FileSystem();
$fs->remove($projectPath.$this->getFilePath());
}
final protected function getBasePath(): string
{
return sprintf('%s/%s', self::BASE_PATH, $this->getSubDir());
}
final protected function getFileName(): string
{
return sprintf('%s.%s', $this->getId(), $this->getExtension());
}
abstract protected function getSubDir(): string;
protected function genExtension(File $file)
{
list(, $type) = explode('/', $file->getMimeType(), 2);
switch ($type) {
case 'pjpeg':
case 'jpeg':
case 'jpg':
return 'jpg';
case 'gif':
return 'gif';
case 'png':
return 'png';
case 'webp':
return 'webp';
default:
return '';
}
}
}
<?php
class Event
{
//........................
/**
* @var Collection|Image[]
*
* @ORM\OneToMany(
* targetEntity="App\Entity\Event\Image",
* orphanRemoval=true,
* mappedBy="event",
* cascade={"persist"}
* )
*/
private $images;
/**
* @return Collection
*/
public function getImages(): Collection
{
return $this->images;
}
/**
* @param Image $image
*
* @return $this
*/
public function addImage(Image $image)
{
if (false === $this->images->contains($image)) {
$image->setEvent($this);
$this->images->add($image);
}
return $this;
}
/**
* @param Image $image
*
* @return $this
*/
public function removeImage(Image $image)
{
$this->images->removeElement($image);
return $this;
}
//........................
}
<?php
declare(strict_types=1);
namespace App\Entity\Event;
use App\Form\Model\AbstractImage;
use Doctrine\ORM\Mapping as ORM;
/**
* Event.
*
* @ORM\Table(
* name="event_image"
* )
* @ORM\Entity
* @ORM\EntityListeners({"App\Event\EntityListener\ImageListener"})
*/
class Image extends AbstractImage
{
/**
* @var Event
*
* @ORM\ManyToOne(
* targetEntity="App\Entity\Event\Event",
* inversedBy="images",
* )
* @ORM\JoinColumn(
* name="event_id",
* referencedColumnName="id"
* )
*/
private $event;
/**
* @return Event|null
*/
public function getEvent(): ?Event
{
return $this->event;
}
/**
* @param Event $event
*/
public function setEvent(Event $event)
{
$this->event = $event;
}
protected function getSubDir(): string
{
return 'event';
}
}
<?php
declare(strict_types=1);
namespace App\Event\EntityListener;
use App\Form\Model\AbstractImage;
use Doctrine\ORM\Mapping\PostPersist;
use Doctrine\ORM\Mapping\PreRemove;
/**
* Class ImageListener.
*/
class ImageListener
{
public const PUBLIC_FOLDER = '/public/';
/** @var string */
private $projectDir;
/**
* ImageListener constructor.
*
* @param string $projectDir
*/
public function __construct(string $projectDir)
{
$this->projectDir = $projectDir.self::PUBLIC_FOLDER;
}
/**
* @PostPersist
*
* @param AbstractImage $image
*/
public function postPersistHandler(AbstractImage $image)
{
$image->saveFile($this->projectDir);
}
/**
* @PreRemove
*
* @param AbstractImage $image
*/
public function preRemoveHandler(AbstractImage $image)
{
$image->removeFile($this->projectDir);
}
}
App\Event\EntityListener\ImageListener:
arguments: [ '%kernel.project_dir%' ]
tags:
- { name: doctrine.orm.entity_listener }
- { name: doctrine.orm.entity_listener, entity_manager: custom }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment