forked from flashii/eeprom
164 lines
6 KiB
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);
|
|
}
|
|
}
|