forked from GNUsocial/gnu-social
[Avatar] Store as regular attachments
This commit is contained in:
parent
c155f4e30e
commit
289eef5cf7
@ -24,10 +24,10 @@ use App\Core\DB\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\GSFile;
|
||||
use App\Core\Modules\Component;
|
||||
use App\Core\Router\Router;
|
||||
use App\Util\Common;
|
||||
use Component\Avatar\Controller as C;
|
||||
use Component\Avatar\Exception\NoAvatarException;
|
||||
use Exception;
|
||||
use Symfony\Component\Asset\Package;
|
||||
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -67,21 +67,22 @@ class Avatar extends Component
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
public function onDeleteCachedAvatar(int $gsactor_id)
|
||||
public function onAvatarUpdate(int $gsactor_id): bool
|
||||
{
|
||||
Cache::delete('avatar-' . $gsactor_id);
|
||||
Cache::delete('avatar-url-' . $gsactor_id);
|
||||
Cache::delete('avatar-file-info-' . $gsactor_id);
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
$gsactor_id = $gsactor_id ?: Common::userNickname();
|
||||
$gsactor_id = $gsactor_id ?: Common::userId();
|
||||
return GSFile::error(NoAvatarException::class,
|
||||
$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
|
||||
{
|
||||
$gsactor_id = $gsactor_id ?: Common::userId();
|
||||
return Cache::get("avatar-url-{$gsactor_id}", function () use ($gsactor_id) {
|
||||
try {
|
||||
return self::getAvatar($gsactor_id)->getUrl();
|
||||
} catch (NoAvatarException $e) {
|
||||
}
|
||||
$attachment_id = self::getAvatarFileInfo($gsactor_id)['id'];
|
||||
if ($attachment_id !== null) {
|
||||
return Router::url('attachment_view', ['id' => $attachment_id]);
|
||||
} else {
|
||||
$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
|
||||
{
|
||||
try {
|
||||
$res = GSFile::error(NoAvatarException::class,
|
||||
$gsactor_id,
|
||||
Cache::get("avatar-file-info-{$gsactor_id}",
|
||||
$res = Cache::get("avatar-file-info-{$gsactor_id}",
|
||||
function () use ($gsactor_id) {
|
||||
return DB::dql('select f.file_hash, f.mimetype, f.title ' .
|
||||
return DB::dql('select f.id, f.filename, f.mimetype, f.title ' .
|
||||
'from App\Entity\Attachment f ' .
|
||||
'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' .
|
||||
'where a.gsactor_id = :gsactor_id',
|
||||
['gsactor_id' => $gsactor_id]);
|
||||
}));
|
||||
$res['file_path'] = Entity\Avatar::getFilePathStatic($res['file_hash']);
|
||||
return $res;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
);
|
||||
if ($res === []) { // Avatar not found
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ use App\Core\GSFile;
|
||||
use App\Core\GSFile as M;
|
||||
use function App\Core\I18n\_m;
|
||||
use App\Core\Log;
|
||||
use App\Core\Security;
|
||||
use App\Util\Common;
|
||||
use App\Util\Exception\ClientException;
|
||||
use App\Util\Exception\NotFoundException;
|
||||
@ -81,7 +82,7 @@ class Avatar extends Controller
|
||||
try {
|
||||
$avatar = DB::findOneBy('avatar', ['gsactor_id' => $gsactor_id]);
|
||||
$avatar->delete();
|
||||
Event::handle('DeleteCachedAvatar', [$user->getId()]);
|
||||
Event::handle('AvatarUpdate', [$user->getId()]);
|
||||
} catch (NotFoundException) {
|
||||
$form->addError(new FormError(_m('No avatar set, so cannot delete')));
|
||||
}
|
||||
@ -107,25 +108,20 @@ class Avatar extends Controller
|
||||
}
|
||||
$attachment = GSFile::validateAndStoreFileAsAttachment(
|
||||
$file,
|
||||
dest_dir: Common::config('avatar', 'dir'),
|
||||
dest_dir: Common::config('attachments', 'dir'),
|
||||
actor_id: $gsactor_id,
|
||||
title: _m("Avatar for Actor {$gsactor_id}"),
|
||||
title: Security::sanitize($file->getClientOriginalName()),
|
||||
is_local: true
|
||||
);
|
||||
// Must get old id before inserting another one
|
||||
$old_attachment = null;
|
||||
// Delete current avatar if there's one
|
||||
$avatar = DB::find('avatar', ['gsactor_id' => $gsactor_id]);
|
||||
$old_attachment = $avatar?->delete();
|
||||
$avatar?->delete();
|
||||
DB::persist($attachment);
|
||||
// Can only get new id after inserting
|
||||
DB::flush();
|
||||
DB::persist(AvatarEntity::create(['gsactor_id' => $gsactor_id, 'attachment_id' => $attachment->getId()]));
|
||||
DB::flush();
|
||||
// Only delete files if the commit went through
|
||||
if ($old_attachment != null) {
|
||||
@unlink($old_attachment);
|
||||
}
|
||||
Event::handle('DeleteCachedAvatar', [$user->getId()]);
|
||||
Event::handle('AvatarUpdate', [$user->getId()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user