Files
webnaplo-gulbaba-api/src/App/Entity/Attachment.php
2018-11-11 12:01:18 +01:00

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(),
];
}
}