Skip to content

Instantly share code, notes, and snippets.

@radynsade
Created January 11, 2023 13:10
Show Gist options
  • Save radynsade/fa1fff6960ce0447f6051e0d671a9c63 to your computer and use it in GitHub Desktop.
Save radynsade/fa1fff6960ce0447f6051e0d671a9c63 to your computer and use it in GitHub Desktop.
<?php
namespace Modules\Upload\Images;
use Core\Framework\Injectable;
use DateTime;
use Modules\Upload\Files\Exceptions\FileNotSavedException;
use Modules\Upload\Files\FilesService;
use Phalcon\Encryption\Security\Random;
use Phalcon\Image\Adapter\Imagick;
use Phalcon\Image\Enum;
use Utils\Files\File;
use Utils\Text\Paths;
class ImagesService extends Injectable {
public const IMAGES_FORMAT = 'webp';
public const IMAGES_QUALITY = 100;
public const MAIN_IMAGE_SIZE = 1280;
public const THUMBNAIL_SIZES = [200, 480, 720];
public const IMAGES_DIR_NAME = 'images';
/**
* @param File $file
* @throws FileNotSavedException
* @return Image
*/
public function upload(File $file): Image {
$mainImageFile = $this->buildMainImage($file);
$filesService = new FilesService();
$image = new Image();
$generatedPath = $this->generatePath($mainImageFile);
$image->setDbFile($filesService->upload(
$mainImageFile,
$generatedPath
));
$thumbnails = [];
$directory = pathinfo($generatedPath, PATHINFO_DIRNAME);
foreach (self::THUMBNAIL_SIZES as $size) {
$filename = $mainImageFile->getShortName() .
'_' . $size .
'.' . self::IMAGES_FORMAT;
$path = Paths::join([$directory, $filename]);
$thumbnails = [
...$thumbnails,
(new Thumbnail())->setImage($image)
->setDbFile($filesService->upload(
$this->buildThumbnailFile(
$mainImageFile,
$size
),
$path
))->setSize($size)
];
}
$image->setThumbnails($thumbnails);
$image->create();
return $image;
}
/**
* @param File $file
* @return File
*/
private function buildMainImage(File $file): File {
$imagick = new Imagick($file->getPath());
if ($imagick->getWidth() > $imagick->getHeight()) {
$imagick->resize(self::MAIN_IMAGE_SIZE, null, Enum::WIDTH);
} else {
$imagick->resize(null, self::MAIN_IMAGE_SIZE, Enum::HEIGHT);
}
$binary = $imagick->render(
self::IMAGES_FORMAT,
self::IMAGES_QUALITY
);
return File::fromBinary($binary);
}
/**
* @param File $imageFile
* @param integer $size
* @return File
*/
private function buildThumbnailFile(
File $imageFile,
int $size
): File {
$imagick = new Imagick($imageFile->getPath());
if ($imagick->getWidth() > $imagick->getHeight()) {
$imagick->resize($size, null, Enum::WIDTH);
} else {
$imagick->resize(null, $size, Enum::HEIGHT);
}
$binary = $imagick->render(
self::IMAGES_FORMAT,
self::IMAGES_QUALITY
);
return File::fromBinary($binary);
}
/**
* @return string
*/
private function generatePath(File $file): string {
$date = new DateTime();
$year = $date->format('Y');
$month = $date->format('m');
$uuid = (new Random())->uuid();
return self::IMAGES_DIR_NAME .
'/' . $year .
'/' . $month .
'/' . $uuid .
'.' . $file->getExtension();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment