[Avatar] Store as regular attachments

This commit is contained in:
Diogo Peralta Cordeiro 2021-08-05 03:15:07 +01:00 committed by Hugo Sales
parent b355f0d590
commit 0c612bddbe
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 35 additions and 37 deletions

View File

@ -24,10 +24,10 @@ use App\Core\DB\DB;
use App\Core\Event; use App\Core\Event;
use App\Core\GSFile; use App\Core\GSFile;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Core\Router\Router;
use App\Util\Common; use App\Util\Common;
use Component\Avatar\Controller as C; use Component\Avatar\Controller as C;
use Component\Avatar\Exception\NoAvatarException; use Component\Avatar\Exception\NoAvatarException;
use Exception;
use Symfony\Component\Asset\Package; use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy; use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -67,21 +67,22 @@ class Avatar extends Component
return Event::next; return Event::next;
} }
public function onDeleteCachedAvatar(int $gsactor_id) public function onAvatarUpdate(int $gsactor_id): bool
{ {
Cache::delete('avatar-' . $gsactor_id); Cache::delete('avatar-' . $gsactor_id);
Cache::delete('avatar-url-' . $gsactor_id); Cache::delete('avatar-url-' . $gsactor_id);
Cache::delete('avatar-file-info-' . $gsactor_id); Cache::delete('avatar-file-info-' . $gsactor_id);
return Event::next;
} }
// UTILS ---------------------------------- // UTILS ----------------------------------
/** /**
* Get the avatar associated with the given nickname * Get the avatar associated with the given GSActor id
*/ */
public static function getAvatar(?int $gsactor_id = null): Entity\Avatar public static function getAvatar(?int $gsactor_id = null): Entity\Avatar
{ {
$gsactor_id = $gsactor_id ?: Common::userNickname(); $gsactor_id = $gsactor_id ?: Common::userId();
return GSFile::error(NoAvatarException::class, return GSFile::error(NoAvatarException::class,
$gsactor_id, $gsactor_id,
Cache::get("avatar-{$gsactor_id}", Cache::get("avatar-{$gsactor_id}",
@ -93,18 +94,19 @@ class Avatar extends Component
} }
/** /**
* Get the cached avatar associated with the given nickname, or the current user if not given * Get the cached avatar associated with the given GSActor id, or the current user if not given
*/ */
public static function getAvatarUrl(?int $gsactor_id = null): string public static function getAvatarUrl(?int $gsactor_id = null): string
{ {
$gsactor_id = $gsactor_id ?: Common::userId(); $gsactor_id = $gsactor_id ?: Common::userId();
return Cache::get("avatar-url-{$gsactor_id}", function () use ($gsactor_id) { return Cache::get("avatar-url-{$gsactor_id}", function () use ($gsactor_id) {
try { $attachment_id = self::getAvatarFileInfo($gsactor_id)['id'];
return self::getAvatar($gsactor_id)->getUrl(); if ($attachment_id !== null) {
} catch (NoAvatarException $e) { return Router::url('attachment_view', ['id' => $attachment_id]);
} else {
$package = new Package(new EmptyVersionStrategy());
return $package->getUrl(Common::config('avatar', 'default'));
} }
$package = new Package(new EmptyVersionStrategy());
return $package->getUrl(Common::config('avatar', 'default'));
}); });
} }
@ -116,22 +118,22 @@ class Avatar extends Component
*/ */
public static function getAvatarFileInfo(int $gsactor_id): array public static function getAvatarFileInfo(int $gsactor_id): array
{ {
try { $res = Cache::get("avatar-file-info-{$gsactor_id}",
$res = GSFile::error(NoAvatarException::class, function () use ($gsactor_id) {
$gsactor_id, return DB::dql('select f.id, f.filename, f.mimetype, f.title ' .
Cache::get("avatar-file-info-{$gsactor_id}", 'from App\Entity\Attachment f ' .
function () use ($gsactor_id) { 'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' .
return DB::dql('select f.file_hash, f.mimetype, f.title ' . 'where a.gsactor_id = :gsactor_id',
'from App\Entity\Attachment f ' . ['gsactor_id' => $gsactor_id]);
'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' . }
'where a.gsactor_id = :gsactor_id', );
['gsactor_id' => $gsactor_id]); if ($res === []) { // Avatar not found
}));
$res['file_path'] = Entity\Avatar::getFilePathStatic($res['file_hash']);
return $res;
} catch (Exception $e) {
$filepath = INSTALLDIR . '/public/assets/default-avatar.svg'; $filepath = INSTALLDIR . '/public/assets/default-avatar.svg';
return ['file_path' => $filepath, 'mimetype' => 'image/svg+xml', 'title' => null]; return ['id' => null, 'file_path' => $filepath, 'mimetype' => 'image/svg+xml', 'title' => null];
} else {
$res = $res[0]; // A user must always only have one avatar.
$res['file_path'] = DB::findOneBy('attachment', ['id' => $res['id']])->getPath();
return $res;
} }
} }
} }

View File

@ -29,6 +29,7 @@ use App\Core\GSFile;
use App\Core\GSFile as M; use App\Core\GSFile as M;
use function App\Core\I18n\_m; use function App\Core\I18n\_m;
use App\Core\Log; use App\Core\Log;
use App\Core\Security;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ClientException; use App\Util\Exception\ClientException;
use App\Util\Exception\NotFoundException; use App\Util\Exception\NotFoundException;
@ -81,7 +82,7 @@ class Avatar extends Controller
try { try {
$avatar = DB::findOneBy('avatar', ['gsactor_id' => $gsactor_id]); $avatar = DB::findOneBy('avatar', ['gsactor_id' => $gsactor_id]);
$avatar->delete(); $avatar->delete();
Event::handle('DeleteCachedAvatar', [$user->getId()]); Event::handle('AvatarUpdate', [$user->getId()]);
} catch (NotFoundException) { } catch (NotFoundException) {
$form->addError(new FormError(_m('No avatar set, so cannot delete'))); $form->addError(new FormError(_m('No avatar set, so cannot delete')));
} }
@ -107,25 +108,20 @@ class Avatar extends Controller
} }
$attachment = GSFile::validateAndStoreFileAsAttachment( $attachment = GSFile::validateAndStoreFileAsAttachment(
$file, $file,
dest_dir: Common::config('avatar', 'dir'), dest_dir: Common::config('attachments', 'dir'),
actor_id: $gsactor_id, actor_id: $gsactor_id,
title: _m("Avatar for Actor {$gsactor_id}"), title: Security::sanitize($file->getClientOriginalName()),
is_local: true is_local: true
); );
// Must get old id before inserting another one // Delete current avatar if there's one
$old_attachment = null; $avatar = DB::find('avatar', ['gsactor_id' => $gsactor_id]);
$avatar = DB::find('avatar', ['gsactor_id' => $gsactor_id]); $avatar?->delete();
$old_attachment = $avatar?->delete();
DB::persist($attachment); DB::persist($attachment);
// Can only get new id after inserting // Can only get new id after inserting
DB::flush(); DB::flush();
DB::persist(AvatarEntity::create(['gsactor_id' => $gsactor_id, 'attachment_id' => $attachment->getId()])); DB::persist(AvatarEntity::create(['gsactor_id' => $gsactor_id, 'attachment_id' => $attachment->getId()]));
DB::flush(); DB::flush();
// Only delete files if the commit went through Event::handle('AvatarUpdate', [$user->getId()]);
if ($old_attachment != null) {
@unlink($old_attachment);
}
Event::handle('DeleteCachedAvatar', [$user->getId()]);
} }
} }