misuzu/src/Users/Assets/UserImageAsset.php
flash d0e3f6ce65 Normalised custom exception usage in user classes.
Also updated the Index library to include the MediaType fix.
2023-07-22 15:02:45 +00:00

123 lines
3.9 KiB
PHP

<?php
namespace Misuzu\Users\Assets;
use InvalidArgumentException;
use RuntimeException;
use Misuzu\Users\User;
abstract class UserImageAsset implements UserImageAssetInterface {
public const PUBLIC_STORAGE = '/msz-storage';
public const TYPE_PNG = IMAGETYPE_PNG;
public const TYPE_JPG = IMAGETYPE_JPEG;
public const TYPE_GIF = IMAGETYPE_GIF;
public const TYPES_EXT = [
self::TYPE_PNG => 'png',
self::TYPE_JPG => 'jpg',
self::TYPE_GIF => 'gif',
];
private $user;
public function __construct(User $user) {
$this->user = $user;
}
public function getUser(): User {
return $this->user;
}
public abstract function getMaxWidth(): int;
public abstract function getMaxHeight(): int;
public abstract function getMaxBytes(): int;
public function getAllowedTypes(): array {
return [self::TYPE_PNG, self::TYPE_JPG, self::TYPE_GIF];
}
public function isAllowedType(int $type): bool {
return in_array($type, $this->getAllowedTypes());
}
private function getImageSize(): array {
return $this->isPresent() && ($imageSize = getimagesize($this->getPath())) ? $imageSize : [];
}
public function getWidth(): int {
return $this->getImageSize()[0] ?? -1;
}
public function getHeight(): int {
return $this->getImageSize()[1] ?? -1;
}
public function getIntType(): int {
return $this->getImageSize()[2] ?? -1;
}
public function getMimeType(): string {
return mime_content_type($this->getPath());
}
public function getFileExtension(): string {
return self::TYPES_EXT[$this->getIntType()] ?? 'img';
}
public abstract function getFileName(): string;
public abstract function getRelativePath(): string;
public function isPresent(): bool {
return is_file($this->getPath());
}
public function getPublicPath(): string {
return self::PUBLIC_STORAGE . '/' . $this->getRelativePath();
}
public function delete(): void {
if($this->isPresent())
unlink($this->getPath());
}
public function getStoragePath(): string {
return MSZ_ROOT . DIRECTORY_SEPARATOR . 'store';
}
public function getPath(): string {
return $this->getStoragePath() . DIRECTORY_SEPARATOR . $this->getRelativePath();
}
public function setFromPath(string $path): void {
if(!is_file($path))
throw new InvalidArgumentException('$path not found.');
$imageInfo = getimagesize($path);
if($imageInfo === false || $imageInfo[0] < 1 || $imageInfo[1] < 1)
throw new InvalidArgumentException('$path is not a valid image.');
if(!self::isAllowedType($imageInfo[2]))
throw new InvalidArgumentException('$path is not an allowed image file.');
if($imageInfo[0] > $this->getMaxWidth() || $imageInfo[1] > $this->getMaxHeight())
throw new InvalidArgumentException('Dimensions of $path are too large.');
if(filesize($path) > $this->getMaxBytes())
throw new InvalidArgumentException('File size of $path is too large.');
$this->delete();
$targetPath = $this->getPath();
$targetDir = dirname($targetPath);
if(!is_dir($targetDir))
mkdir($targetDir, 0775, true);
if(is_uploaded_file($path) ? !move_uploaded_file($path, $targetPath) : !copy($path, $targetPath))
throw new RuntimeException('Was unable to move $path to the storage destination.');
}
public function setFromData(string $data): void {
$file = tempnam(sys_get_temp_dir(), 'msz');
if($file === false || !is_file($file))
throw new RuntimeException('Failed to apply user asset data.');
chmod($file, 0664);
file_put_contents($file, $data);
self::setFromPath($file);
unlink($file);
}
}