misuzu/src/Users/Assets/UserAvatarAsset.php
flash 383e2ed0e0 Rewrote the user information class.
This one took multiple days and it pretty invasive into the core of Misuzu so issue might (will) arise, there's also some features that have gone temporarily missing in the mean time and some inefficiencies introduced that will be fixed again at a later time.
The old class isn't gone entirely because I still have to figure out what I'm gonna do about validation, but for the most part this knocks out one of the "layers of backwards compatibility", as I've been referring to it, and is moving us closer to a future where Flashii actually gets real updates.
If you run into anything that's broken and you're inhibited from reporting it through the forum, do it through chat or mail me at flashii-issues@flash.moe.
2023-08-02 22:12:47 +00:00

112 lines
3.7 KiB
PHP

<?php
namespace Misuzu\Users\Assets;
use Misuzu\Imaging\Image;
class UserAvatarAsset extends UserImageAsset implements UserAssetScalableInterface {
private const FORMAT = 'avatars/%s/%d.msz';
private const DIR_ORIG = 'original';
private const DIR_SIZE = '%1$dx%1$d';
public const DEFAULT_DIMENSION = 200;
public const DIMENSIONS = [
40, 60, 80, 100, 120, 200, 240,
];
private const MAX_RES = 2000;
private const MAX_BYTES = 1000000;
public function getMaxWidth(): int {
global $cfg;
return $cfg->getInteger('avatar.max_res', self::MAX_RES);
}
public function getMaxHeight(): int {
return $this->getMaxWidth();
}
public function getMaxBytes(): int {
global $cfg;
return $cfg->getInteger('avatar.max_size', self::MAX_BYTES);
}
public function getUrl(): string {
return url('user-avatar', ['user' => $this->getUserId()]);
}
public function getScaledUrl(int $dims): string {
return url('user-avatar', ['user' => $this->getUserId(), 'res' => $dims]);
}
public static function clampDimensions(int $dimensions): int {
$closest = null;
foreach(self::DIMENSIONS as $dims)
if($closest === null || abs($dimensions - $closest) >= abs($dims - $dimensions))
$closest = $dims;
return $closest;
}
public function getFileName(): string {
return sprintf('avatar-%1$d.%2$s', $this->getUserId(), $this->getFileExtension());
}
public function getScaledFileName(int $dims): string {
return sprintf('avatar-%1$d-%3$dx%3$d.%2$s', $this->getUserId(), $this->getScaledFileExtension($dims), self::clampDimensions($dims));
}
public function getScaledMimeType(int $dims): string {
if(!$this->isScaledPresent($dims))
return '';
return mime_content_type($this->getScaledPath($dims));
}
public function getScaledFileExtension(int $dims): string {
$imageSize = getimagesize($this->getScaledPath($dims));
if($imageSize === false)
return 'img';
return self::TYPES_EXT[$imageSize[2]] ?? 'img';
}
public function getRelativePath(): string {
return sprintf(self::FORMAT, self::DIR_ORIG, $this->getUserId());
}
public function getScaledRelativePath(int $dims): string {
$dims = self::clampDimensions($dims);
return sprintf(self::FORMAT, sprintf(self::DIR_SIZE, $dims), $this->getUserId());
}
public function getScaledPath(int $dims): string {
return $this->getStoragePath() . DIRECTORY_SEPARATOR . $this->getScaledRelativePath($dims);
}
public function isScaledPresent(int $dims): bool {
return is_file($this->getScaledPath($dims));
}
public function deleteScaled(int $dims): void {
if($this->isScaledPresent($dims))
unlink($this->getScaledPath($dims));
}
public function ensureScaledExists(int $dims): void {
if(!$this->isPresent())
return;
$dims = self::clampDimensions($dims);
if($this->isScaledPresent($dims))
return;
$scaledPath = $this->getScaledPath($dims);
$scaledDir = dirname($scaledPath);
if(!is_dir($scaledDir))
mkdir($scaledDir, 0775, true);
$scale = Image::create($this->getPath());
$scale->squareCrop($dims);
$scale->save($scaledPath);
$scale->destroy();
}
public function getPublicScaledPath(int $dims): string {
return self::PUBLIC_STORAGE . '/' . $this->getScaledRelativePath($dims);
}
public function delete(): void {
parent::delete();
foreach(self::DIMENSIONS as $dims)
$this->deleteScaled($dims);
}
}