'png', self::TYPE_JPG => 'jpg', self::TYPE_GIF => 'gif', ]; protected string $userId; public function __construct(UserInfo $userInfo) { $this->userId = (string)$userInfo->getId(); } public function getUserId(): string { return $this->userId; } 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); } }