347 lines
7.8 KiB
PHP
347 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Entity;
|
|
|
|
use Doctrine\ORM\Event\LifecycleEventArgs;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
use Imagine\Image\Box;
|
|
use Imagine\Image\ImageInterface;
|
|
use Imagine\Gd\Imagine;
|
|
use JsonSerializable;
|
|
|
|
/**
|
|
* @ORM\Entity
|
|
* @ORM\Table(
|
|
* name="attachments",
|
|
* indexes={
|
|
* @ORM\Index(name="AT_type_idx", columns={"type"}),
|
|
* @ORM\Index(name="AT_active_idx", columns={"active"})
|
|
* }
|
|
* )
|
|
* @ORM\HasLifecycleCallbacks
|
|
*/
|
|
class Attachment implements JsonSerializable
|
|
{
|
|
|
|
const MAX_PIXEL_SPREAD = 3200;
|
|
|
|
/**
|
|
* @ORM\Id
|
|
* @ORM\Column(name="id", type="integer")
|
|
* @ORM\GeneratedValue(strategy="IDENTITY")
|
|
* @var int
|
|
*/
|
|
private $id;
|
|
|
|
/**
|
|
* @ORM\JoinColumn(name="fault_id", nullable=false)
|
|
* @ORM\ManyToOne(targetEntity="Fault", inversedBy="attachments")
|
|
* @var Fault
|
|
*/
|
|
private $fault;
|
|
|
|
/**
|
|
* @ORM\JoinColumn(name="user_id", nullable=false)
|
|
* @ORM\ManyToOne(targetEntity="User", inversedBy="attachments")
|
|
* @var User
|
|
*/
|
|
private $user;
|
|
|
|
/**
|
|
* Type can be image or invoice
|
|
*
|
|
* @ORM\Column(name="type", type="string", length=50, nullable=false)
|
|
* @var string
|
|
*/
|
|
private $type = 'image';
|
|
|
|
/**
|
|
* @ORM\Column(name="active", type="boolean", options={"default": true})
|
|
* @var bool
|
|
*/
|
|
private $active = true;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $rawFileData = null;
|
|
|
|
/**
|
|
* Temporary variably, only used for entity postRemove hook
|
|
*
|
|
* @var int
|
|
*/
|
|
private $idPreDeleteTemp;
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getId()
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
* @return Attachment
|
|
*/
|
|
public function setId(int $id): Attachment
|
|
{
|
|
$this->id = $id;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return Fault
|
|
*/
|
|
public function getFault(): Fault
|
|
{
|
|
return $this->fault;
|
|
}
|
|
|
|
/**
|
|
* @param Fault $fault
|
|
* @return Attachment
|
|
*/
|
|
public function setFault(Fault $fault)
|
|
{
|
|
$this->fault = $fault;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return User
|
|
*/
|
|
public function getUser(): User
|
|
{
|
|
return $this->user;
|
|
}
|
|
|
|
/**
|
|
* @param User $user
|
|
* @return Attachment
|
|
*/
|
|
public function setUser(User $user): Attachment
|
|
{
|
|
$this->user = $user;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getType(): string
|
|
{
|
|
return $this->type;
|
|
}
|
|
|
|
/**
|
|
* @param string $type
|
|
* @return Attachment
|
|
*/
|
|
public function setType(string $type): Attachment
|
|
{
|
|
$this->type = $type;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return boolean
|
|
*/
|
|
public function getActive(): bool
|
|
{
|
|
return $this->active;
|
|
}
|
|
|
|
/**
|
|
* @param boolean $active
|
|
* @return Attachment
|
|
*/
|
|
public function setActive(bool $active): Attachment
|
|
{
|
|
$this->active = $active;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getRawFileData(): string
|
|
{
|
|
return $this->rawFileData;
|
|
}
|
|
|
|
/**
|
|
* @param string $rawFileData
|
|
* @return Attachment
|
|
*/
|
|
public function setRawFileData(string $rawFileData): Attachment
|
|
{
|
|
$this->rawFileData = $rawFileData;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @ORM\PrePersist
|
|
* @return Attachment
|
|
*/
|
|
public function validatePrePersist(): Attachment
|
|
{
|
|
if ($this->getRawFileData() == null) {
|
|
throw new \InvalidArgumentException("File data can't be empty");
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @ORM\PostPersist
|
|
* @return Attachment
|
|
*/
|
|
public function saveOnPersist(): Attachment
|
|
{
|
|
if ($this->getType() == 'image') {
|
|
return $this->saveDataAsImageFile($this->rawFileData);
|
|
}
|
|
|
|
return $this->saveDataAsBinaryFile($this->rawFileData);
|
|
}
|
|
|
|
/**
|
|
* @ORM\PreRemove
|
|
* @return Attachment
|
|
*/
|
|
public function preDeleteHelper(): Attachment
|
|
{
|
|
$this->idPreDeleteTemp = $this->id;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @ORM\PostRemove
|
|
* @return Attachment
|
|
*/
|
|
public function deleteImage(): Attachment
|
|
{
|
|
unlink($this->getFileName($this->idPreDeleteTemp));
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $rawFileData
|
|
* @return Attachment
|
|
*/
|
|
public function saveDataAsImageFile(string $rawFileData): Attachment
|
|
{
|
|
$folder = $this->getContainingFolder();
|
|
if (!file_exists($folder)) {
|
|
mkdir($folder, 0755, true);
|
|
}
|
|
|
|
$extendedId = $this->getExtendedId();
|
|
$pathSplit = str_split($extendedId, 3);
|
|
$fileName = array_pop($pathSplit);
|
|
$imagine = new Imagine();
|
|
$image = $imagine->load($rawFileData);
|
|
$originBox = $image->getSize();
|
|
$originWidth = $originBox->getWidth();
|
|
$originHeight = $originBox->getHeight();
|
|
if ($originWidth > self::MAX_PIXEL_SPREAD || $originHeight > self::MAX_PIXEL_SPREAD) {
|
|
if ($originWidth > $originHeight) {
|
|
$newWidth = self::MAX_PIXEL_SPREAD;
|
|
$newHeight = floor(self::MAX_PIXEL_SPREAD * $originHeight / $originWidth);
|
|
} elseif ($originHeight > $originWidth) {
|
|
$newWidth = floor(self::MAX_PIXEL_SPREAD * $originWidth / $originHeight);
|
|
$newHeight = self::MAX_PIXEL_SPREAD;
|
|
} else {
|
|
$newWidth = self::MAX_PIXEL_SPREAD;
|
|
$newHeight = self::MAX_PIXEL_SPREAD;
|
|
}
|
|
// $image->resize(new Box($newWidth, $newHeight), ImageInterface::FILTER_LANCZOS);
|
|
$image->resize(new Box($newWidth, $newHeight));
|
|
$image->effects()->sharpen();
|
|
}
|
|
$image->save(sprintf("%s/%s", $folder, $fileName), [
|
|
'format' => 'jpeg',
|
|
'jpeg_quality' => 80,
|
|
]);
|
|
return $this;
|
|
}
|
|
|
|
public function saveDataAsBinaryFile(string $rawFileData): Attachment
|
|
{
|
|
$folder = $this->getContainingFolder();
|
|
if (!file_exists($folder)) {
|
|
mkdir($folder, 0755, true);
|
|
}
|
|
$pathSplit = str_split($this->getExtendedId(), 3);
|
|
$fileName = array_pop($pathSplit);
|
|
file_put_contents(sprintf("%s/%s", $folder, $fileName), $rawFileData);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
* @return string
|
|
*/
|
|
private function getContainingFolder($id = null): string
|
|
{
|
|
$attachmentFolder = str_split($this->getExtendedId($id), 3);
|
|
array_pop($attachmentFolder);
|
|
return sprintf('data/attachments/%s', implode('/', $attachmentFolder));
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
private function getExtendedId($id = null): string
|
|
{
|
|
if ($this->id == null && $id == null) {
|
|
throw new \Exception("Entity must be persisted first.");
|
|
}
|
|
|
|
return sprintf("%09d", $id ? $id : $this->getId());
|
|
}
|
|
|
|
/**
|
|
* @param int $id
|
|
* @return string
|
|
*/
|
|
public function getFileName($id = null): string
|
|
{
|
|
$splitParts = str_split($this->getExtendedId($id), 3);
|
|
$fileName = array_pop($splitParts);
|
|
return sprintf("%s/%s", $this->getContainingFolder($id), $fileName);
|
|
}
|
|
|
|
/**
|
|
* @return resource
|
|
*/
|
|
public function getIoStream()
|
|
{
|
|
return fopen($this->getFileName(), 'r');
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getRawAttachmentData(): string
|
|
{
|
|
return file_get_contents($this->getFileName());
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function jsonSerialize()
|
|
{
|
|
return [
|
|
'id' => $this->getId(),
|
|
'type' => $this->getType(),
|
|
'active' => $this->getActive(),
|
|
'user' => $this->getUser(),
|
|
];
|
|
}
|
|
}
|