119 lines
4.4 KiB
PHP
119 lines
4.4 KiB
PHP
<?php
|
|
namespace Misuzu\Users\Assets;
|
|
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use Index\Routing\IRouter;
|
|
use Misuzu\Perm;
|
|
use Misuzu\Auth\AuthInfo;
|
|
use Misuzu\Users\Bans;
|
|
use Misuzu\Users\Users;
|
|
use Misuzu\Users\UserInfo;
|
|
|
|
class AssetsRoutes {
|
|
private AuthInfo $authInfo;
|
|
private Bans $bans;
|
|
private Users $users;
|
|
|
|
public function __construct(IRouter $router, AuthInfo $authInfo, Bans $bans, Users $users) {
|
|
$this->authInfo = $authInfo;
|
|
$this->bans = $bans;
|
|
$this->users = $users;
|
|
|
|
$router->get('/assets/avatar', [$this, 'getAvatar']);
|
|
$router->get('/assets/avatar/:filename', [$this, 'getAvatar']);
|
|
$router->get('/assets/profile-background', [$this, 'getProfileBackground']);
|
|
$router->get('/assets/profile-background/:filename', [$this, 'getProfileBackground']);
|
|
$router->get('/user-assets.php', [$this, 'getUserAssets']);
|
|
}
|
|
|
|
private function canViewAsset($request, UserInfo $assetUser): bool {
|
|
if($this->bans->countActiveBans($assetUser))
|
|
// allow staff viewing profile to still see banned user assets
|
|
return $this->authInfo->getPerms('user')->check(Perm::U_USERS_MANAGE)
|
|
&& parse_url($request->getHeaderFirstLine('Referer'), PHP_URL_PATH) === url('user-profile');
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getAvatar($response, $request, string $fileName = '') {
|
|
$userId = pathinfo($fileName, PATHINFO_FILENAME);
|
|
$assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/no-avatar.png', MSZ_PUBLIC);
|
|
|
|
try {
|
|
$userInfo = $this->users->getUser($userId, 'id');
|
|
|
|
if(!$this->canViewAsset($request, $userInfo)) {
|
|
$assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/banned-avatar.png', MSZ_PUBLIC);
|
|
} else {
|
|
$userAssetInfo = new UserAvatarAsset($userInfo);
|
|
if($userAssetInfo->isPresent())
|
|
$assetInfo = $userAssetInfo;
|
|
}
|
|
} catch(RuntimeException $ex) {
|
|
} catch(InvalidArgumentException $ex) {}
|
|
|
|
return $this->serveAsset($response, $request, $assetInfo);
|
|
}
|
|
|
|
public function getProfileBackground($response, $request, string $fileName = '') {
|
|
$userId = pathinfo($fileName, PATHINFO_FILENAME);
|
|
|
|
try {
|
|
$userInfo = $this->users->getUser($userId, 'id');
|
|
} catch(RuntimeException $ex) {
|
|
} catch(InvalidArgumentException $ex) {}
|
|
|
|
if(!empty($userInfo)) {
|
|
$userAssetInfo = new UserBackgroundAsset($userInfo);
|
|
if($userAssetInfo->isPresent() && $this->canViewAsset($request, $userInfo))
|
|
$assetInfo = $userAssetInfo;
|
|
}
|
|
|
|
if(!isset($assetInfo)) {
|
|
// circumvent the default error page
|
|
$response->setContent('Not Found');
|
|
return 404;
|
|
}
|
|
|
|
return $this->serveAsset($response, $request, $assetInfo);
|
|
}
|
|
|
|
public function getUserAssets($response, $request) {
|
|
$userId = (string)$request->getParam('u', FILTER_SANITIZE_NUMBER_INT);
|
|
$mode = (string)$request->getParam('m');
|
|
|
|
if($mode === 'avatar')
|
|
return $this->getAvatar($response, $request, $userId);
|
|
|
|
if($mode === 'background')
|
|
return $this->getProfileBackground($response, $request, $userId);
|
|
|
|
// circumvent the default error page
|
|
$response->setContent('Not Found');
|
|
return 404;
|
|
}
|
|
|
|
private function serveAsset($response, $request, UserImageAssetInterface $assetInfo): void {
|
|
$contentType = $assetInfo->getMimeType();
|
|
$publicPath = $assetInfo->getPublicPath();
|
|
$fileName = $assetInfo->getFileName();
|
|
|
|
if($assetInfo instanceof UserAssetScalableInterface) {
|
|
$dimensions = (int)($request->getParam('res', FILTER_SANITIZE_NUMBER_INT)
|
|
?? $request->getParam('r', FILTER_SANITIZE_NUMBER_INT));
|
|
|
|
if($dimensions > 0) {
|
|
$assetInfo->ensureScaledExists($dimensions);
|
|
$contentType = $assetInfo->getScaledMimeType($dimensions);
|
|
$publicPath = $assetInfo->getPublicScaledPath($dimensions);
|
|
$fileName = $assetInfo->getScaledFileName($dimensions);
|
|
}
|
|
}
|
|
|
|
$response->accelRedirect($publicPath);
|
|
$response->setContentType($contentType);
|
|
$response->setFileName($fileName, false);
|
|
}
|
|
}
|