gallery-api/src/App/Service/GalleryService.php

200 lines
5.7 KiB
PHP
Raw Normal View History

2017-07-21 19:59:16 +02:00
<?php
namespace App\Service;
2017-08-12 22:56:25 +02:00
use App\Entity\Image;
use Doctrine\ORM\EntityManager;
2017-07-21 19:59:16 +02:00
use Imagine\Gd\Imagine;
use Imagine\Image\Box;
use Imagine\Image\ImageInterface;
use Symfony\Component\Yaml\Parser;
use Zend\Config\Reader\Yaml;
class GalleryService
{
2017-08-09 15:47:05 +02:00
const CONFIG_FILE = 'data/galleries/config.yaml';
const IMAGE_BASEDIR = 'data/galleries/%s/';
2017-08-15 00:32:07 +02:00
const EXPORT_DIR = 'data/export/';
2017-08-12 17:39:17 +02:00
const THUMBNAIL_SIZE = 500;
2017-08-09 15:47:05 +02:00
protected $contentTypeMap = [
2017-08-12 22:56:25 +02:00
'jpg' => 'image/jpeg',
2017-08-09 15:47:05 +02:00
'jpeg' => 'image/jpeg',
2017-08-12 22:56:25 +02:00
'png' => 'image/png',
2017-08-09 15:47:05 +02:00
];
protected $config;
2017-08-12 22:56:25 +02:00
/**
* @var EntityManager
*/
protected $em;
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
2017-08-15 00:32:07 +02:00
public function getExportFileName(string $slug)
{
$config = $this->getConfig();
if (!isset($config['galleries'][$slug])) {
return false;
}
$dir = $config['galleries'][$slug]['dir'];
2017-08-15 00:32:07 +02:00
return $this->ensureExportFileExists($dir, "{$slug}.zip");
}
private function ensureExportFileExists(string $dir, string $filename)
{
$exportName = self::EXPORT_DIR . $filename;
if(file_exists($exportName)) {
return $exportName;
}
$images = array_map('basename', glob($this->getImageDir($dir) . "*.{jpg,jpeg,png}", GLOB_BRACE));
$zipName = tempnam("data/tmp", "export");
$zipArchive = new \ZipArchive();
$zipArchive->open($zipName, \ZipArchive::CREATE);
foreach ($images as $image) {
2017-08-15 00:32:07 +02:00
ini_set("max_execution_time", 60);
$zipArchive->addFile(
sprintf(self::IMAGE_BASEDIR,$dir) . $image,
"{$dir}/{$image}"
);
}
$zipArchive->close();
2017-08-15 00:32:07 +02:00
rename($zipName, $exportName);
return $exportName;
}
2017-08-09 15:47:05 +02:00
public function loadGalleryData($includeHidden = false)
{
$config = $this->getConfig();
2017-08-12 22:56:25 +02:00
$albums = [];
2017-08-09 15:47:05 +02:00
foreach ($config['galleries'] as $id => $data) {
if ($includeHidden || $data['public']) {
$galleryImages = $this->loadGalleryImages($data['dir']);
2017-08-12 22:56:25 +02:00
$albums[] = [
2017-08-09 15:47:05 +02:00
'slug' => $id,
'name' => $data['name'],
'coverImage' => isset($data['cover'])
? $this->getCoverImage($galleryImages, $data['cover'])
2017-08-09 15:47:05 +02:00
: null,
'date' => $this->getGalleryDate($data['dir']),
'type' => $data['type'],
'isNew' => $data['new'],
'isPublic' => $data['public'],
'images' => $galleryImages,
2017-08-09 15:47:05 +02:00
];
}
2017-07-21 19:59:16 +02:00
}
2017-08-12 22:56:25 +02:00
return $albums;
2017-08-09 15:47:05 +02:00
}
private function getCoverImage(array &$images, string $coverFileName): Image
{
$filtered = array_values(array_filter($images, function(Image $image) use ($coverFileName) {
return $image->getPath() == $coverFileName;
}));
return array_pop($filtered);
}
2017-08-09 15:47:05 +02:00
private function getGalleryDate(string $dir): string
{
$timestamp = sprintf("@%s", filemtime($this->getImageDir($dir)));
2017-08-09 15:47:05 +02:00
$date = new \DateTime($timestamp);
return $date->format("Y-m-d");
}
/**
* @param string $dir
2017-08-12 22:56:25 +02:00
* @return Image[]
2017-08-09 15:47:05 +02:00
* @todo implement label for image in some way
*/
2017-08-12 22:56:25 +02:00
private function loadGalleryImages(string $dir): array
2017-08-09 15:47:05 +02:00
{
$images = array_map('basename', glob(
sprintf(self::IMAGE_BASEDIR . "*.{jpg,jpeg,png}", $dir),
GLOB_BRACE
));
2017-08-12 22:56:25 +02:00
$imagine = new Imagine();
return array_map(function ($imagePath) use ($dir, $imagine) {
2017-08-12 22:56:25 +02:00
$imageEntity = $this->em->getRepository(Image::class)->findOneBy([
'dir' => $dir,
'path' => $imagePath,
2017-08-12 22:56:25 +02:00
]);
$this->ensureThumbnailExists($dir, $imagePath);
2017-08-12 22:56:25 +02:00
if (null === $imageEntity) {
$image = $imagine->open($this->getImageDir($dir) . $imagePath);
$imageSize = $image->getSize();
unset($image);
$thumb = $imagine->open($this->getThumbDir($dir) . $imagePath);
$thumbSize = $thumb->getSize();
unset($thumb);
2017-08-12 22:56:25 +02:00
$imageEntity = new Image();
$imageEntity->setLabel("")
->setDir($dir)
->setPath($imagePath)
->setWidth($imageSize->getWidth())
->setHeight($imageSize->getHeight())
->setThumbWidth($thumbSize->getWidth())
->setThumbHeight($thumbSize->getHeight())
;
2017-08-12 22:56:25 +02:00
$this->em->persist($imageEntity);
$this->em->flush();
}
return $imageEntity;
2017-08-09 15:47:05 +02:00
}, $images);
}
private function ensureThumbnailExists(string $dir, string $imageName) {
$imageDir = $this->getImageDir($dir);
$thumbPath = $imageDir . "thumb_" . self::THUMBNAIL_SIZE;
2017-08-09 15:47:05 +02:00
@mkdir($thumbPath);
$thumbImageName = $thumbPath . "/" . $imageName;
if (!file_exists($thumbImageName)) {
$thumbSize = new Box(self::THUMBNAIL_SIZE, self::THUMBNAIL_SIZE * 10);
2017-08-09 15:47:05 +02:00
$imagine = new Imagine();
$image = $imagine->open($imageDir . $imageName)
2017-08-12 17:39:17 +02:00
->thumbnail($thumbSize, ImageInterface::THUMBNAIL_INSET);
2017-08-09 15:47:05 +02:00
$image->effects()->sharpen();
$image->save($thumbImageName);
}
return $thumbImageName;
}
2017-07-21 19:59:16 +02:00
public function getImageFileName(string $slug, string $image, $isThumbnail = false): string
{
$config = $this->getConfig();
$dir = $config['galleries'][$slug]['dir'];
$this->ensureThumbnailExists($config['galleries'][$slug]['dir'], $image);
return $isThumbnail
? ($this->getThumbDir($dir) . $image)
: ($this->getImageDir($dir) . $image);
}
private function getImageDir($dir): string {
return sprintf(self::IMAGE_BASEDIR, $dir);
}
private function getThumbDir($dir): string {
return sprintf(self::IMAGE_BASEDIR, "{$dir}/thumb_" . self::THUMBNAIL_SIZE);
}
private function getConfig()
2017-08-09 15:47:05 +02:00
{
if (null === $this->config) {
$parser = new Parser();
$configReader = new Yaml([$parser, 'parse']);
$this->config = $configReader->fromFile(self::CONFIG_FILE);
2017-07-21 19:59:16 +02:00
}
2017-08-09 15:47:05 +02:00
return $this->config;
}
2017-07-21 19:59:16 +02:00
}