2
0
Fork 0
forked from flashii/eeprom
eeprom-nabucco/src/Uploads/UploadsContext.php

164 lines
6 KiB
PHP

<?php
namespace EEPROM\Uploads;
use Imagick;
use Index\Data\IDbConnection;
use Syokuhou\IConfig;
use EEPROM\FFMPEG;
class UploadsContext {
private IConfig $config;
private UploadsData $uploadsData;
public function __construct(IConfig $config, IDbConnection $dbConn) {
$this->config = $config;
$this->uploadsData = new UploadsData($dbConn);
}
public function getUploadsData(): UploadsData {
return $this->uploadsData;
}
public function getFileDataPath(UploadInfo $uploadInfo): string {
return sprintf('%s%s%s', PRM_UPLOADS, DIRECTORY_SEPARATOR, $uploadInfo->getId());
}
public function getThumbnailDataPath(UploadInfo $uploadInfo): string {
return sprintf('%s%s%s', PRM_THUMBS, DIRECTORY_SEPARATOR, $uploadInfo->getId());
}
public function getFileDataRedirectPath(UploadInfo $uploadInfo): string {
return sprintf('%s%s%s', str_replace(PRM_PUBLIC, '', PRM_UPLOADS), DIRECTORY_SEPARATOR, $uploadInfo->getId());
}
public function getThumbnailDataRedirectPath(UploadInfo $uploadInfo): string {
return sprintf('%s%s%s', str_replace(PRM_PUBLIC, '', PRM_THUMBS), DIRECTORY_SEPARATOR, $uploadInfo->getId());
}
public function getThumbnailDataPathOrCreate(UploadInfo $uploadInfo): string {
if(!$this->supportsThumbnailing($uploadInfo))
return '';
$thumbPath = $this->getThumbnailDataPath($uploadInfo);
if(is_file($thumbPath))
return $thumbPath;
return $this->createThumbnailInternal(
$uploadInfo,
$this->getFileDataPath($uploadInfo),
$thumbPath
);
}
public function getThumbnailDataRedirectPathOrCreate(UploadInfo $uploadInfo): string {
return str_replace(PRM_PUBLIC, '', $this->getThumbnailDataPathOrCreate($uploadInfo));
}
public function getFileUrlV1(UploadInfo $uploadInfo, bool $forceApiDomain = false): string {
if(!$forceApiDomain && $this->config->hasValues('domain:short'))
return sprintf('//%s/%s', $this->config->getString('domain:short'), $uploadInfo->getId());
return sprintf('//%s/uploads/%s', $this->config->getString('domain:api'), $uploadInfo->getId());
}
public function getThumbnailUrlV1(UploadInfo $uploadInfo, bool $forceApiDomain = false): string {
return sprintf('%s.t', $this->getFileUrlV1($uploadInfo, $forceApiDomain));
}
public function convertToClientJsonV1(UploadInfo $uploadInfo): array {
return [
'id' => $uploadInfo->getId(),
'url' => $this->getFileUrlV1($uploadInfo),
'urlf' => $this->getFileUrlV1($uploadInfo, true),
'thumb' => $this->getThumbnailUrlV1($uploadInfo),
'name' => $uploadInfo->getName(),
'type' => $uploadInfo->getMediaTypeString(),
'size' => $uploadInfo->getDataSize(),
'user' => (int)$uploadInfo->getUserId(),
'appl' => (int)$uploadInfo->getAppId(),
'hash' => $uploadInfo->getHashString(),
'created' => str_replace('+00:00', 'Z', $uploadInfo->getCreatedAt()->format(\DateTime::ATOM)),
'accessed' => $uploadInfo->hasBeenAccessed() ? str_replace('+00:00', 'Z', $uploadInfo->getAccessedAt()->format(\DateTime::ATOM)) : null,
'expires' => $uploadInfo->hasExpired() ? str_replace('+00:00', 'Z', $uploadInfo->getExpiredAt()->format(\DateTime::ATOM)) : null,
// These can never be reached, and in situation where they technically could it's because of an outdated local record
'deleted' => null,
'dmca' => null,
];
}
public function supportsThumbnailing(UploadInfo $uploadInfo): bool {
return $uploadInfo->isImage()
|| $uploadInfo->isAudio()
|| $uploadInfo->isVideo();
}
public function createThumbnail(UploadInfo $uploadInfo): string {
if(!$this->supportsThumbnailing($uploadInfo))
return '';
return $this->createThumbnailInternal(
$uploadInfo,
$this->getFileDataPath($uploadInfo),
$this->getThumbnailDataPath($uploadInfo)
);
}
private function createThumbnailInternal(UploadInfo $uploadInfo, string $filePath, string $thumbPath): string {
$imagick = new Imagick;
if($uploadInfo->isImage()) {
$imagick->readImageBlob(file_get_contents($filePath));
} elseif($uploadInfo->isAudio())
$imagick->readImageBlob(FFMPEG::grabAudioCover($filePath));
elseif($uploadInfo->isVideo())
$imagick->readImageBlob(FFMPEG::grabVideoFrame($filePath));
$imagick->setImageFormat('jpg');
$imagick->setImageCompressionQuality($this->config->getInteger('thumb:quality', 40));
$thumbRes = $this->config->getInteger('thumb:dimensions', 100);
$width = $imagick->getImageWidth();
$height = $imagick->getImageHeight();
if($width === $height) {
$resizeWidth = $resizeHeight = $thumbRes;
} elseif($width > $height) {
$resizeWidth = $width * $thumbRes / $height;
$resizeHeight = $thumbRes;
} else {
$resizeWidth = $thumbRes;
$resizeHeight = $height * $thumbRes / $width;
}
$resizeWidth = (int)$resizeWidth;
$resizeHeight = (int)$resizeHeight;
$imagick->resizeImage(
$resizeWidth, $resizeHeight,
Imagick::FILTER_GAUSSIAN, 0.7
);
$imagick->cropImage(
$thumbRes,
$thumbRes,
(int)ceil(($resizeWidth - $thumbRes) / 2),
(int)ceil(($resizeHeight - $thumbRes) / 2)
);
$imagick->writeImage($thumbPath);
return is_file($thumbPath) ? $thumbPath : '';
}
public function deleteUploadData(UploadInfo|string $uploadInfo): void {
$filePath = $this->getFileDataPath($uploadInfo);
if(is_file($filePath))
unlink($filePath);
$thumbPath = $this->getThumbnailDataPath($uploadInfo);
if(is_file($thumbPath))
unlink($thumbPath);
}
}