From 33fba0d970b8f802992e629b98bd1fbae45fc1d7 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Fri, 10 Dec 2021 10:19:01 +0000 Subject: [PATCH] [COMPONENT][Language][ENTITY][ActorLanguage] Refactor cache keys in ActorLanguage. Add ActorLangauge::getActorRelatedLanguagesIds and use it in note filtering in the Language component --- components/Language/Language.php | 11 ++-------- src/Controller/UserPanel.php | 4 ++-- src/Entity/ActorLanguage.php | 37 ++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/components/Language/Language.php b/components/Language/Language.php index 621bd9b013..0dd9932177 100644 --- a/components/Language/Language.php +++ b/components/Language/Language.php @@ -21,10 +21,10 @@ declare(strict_types = 1); namespace Component\Language; -use App\Core\DB\DB; use App\Core\Event; use App\Core\Modules\Component; use App\Entity\Actor; +use App\Entity\ActorLanguage; use App\Entity\Note; use Functional as F; @@ -32,16 +32,9 @@ class Language extends Component { public function onFilterNoteList(Actor $actor, array &$notes) { - $language = $actor->getTopLanguage(); - $locale = explode('_', $language->getLocale())[0]; - $language_family = F\reindex( - DB::dql('select l from language l where l.locale like :locale', ['locale' => $locale . '%']), - fn ($l) => $l->getId(), - ); - $notes = F\select( $notes, - fn (Note $n) => \array_key_exists($n->getLanguageId(), $language_family) && !str_contains($language_family[$n->getLanguageId()]->getLocale(), '_') ? \in_array($n->getLanguageId(), array_keys($language_family)) : $n->getLanguageId() === $language->getId(), + fn (Note $n) => \in_array($n->getLanguageId(), ActorLanguage::getActorRelatedLanguagesIds($actor)), ); return Event::next; diff --git a/src/Controller/UserPanel.php b/src/Controller/UserPanel.php index 6c46338b60..8957bf7cda 100644 --- a/src/Controller/UserPanel.php +++ b/src/Controller/UserPanel.php @@ -215,9 +215,9 @@ class UserPanel extends Controller } } - Cache::delete(ActorLanguage::collectionCacheKey($user)); - DB::flush(); + Cache::delete(ActorLanguage::cacheKeys($user)['actor-langs']); ActorLanguage::normalizeOrdering($user); // In case the user doesn't submit the other page + DB::flush(); unset($data['languages']); throw new RedirectException('settings_sort_languages', ['_fragment' => null]); // TODO doesn't clear fragment diff --git a/src/Entity/ActorLanguage.php b/src/Entity/ActorLanguage.php index cfdefd18be..3c126d3006 100644 --- a/src/Entity/ActorLanguage.php +++ b/src/Entity/ActorLanguage.php @@ -27,6 +27,7 @@ use App\Core\Cache; use App\Core\DB\DB; use App\Core\Entity; use App\Util\Common; +use Functional as F; /** * Entity for actor languages @@ -81,9 +82,13 @@ class ActorLanguage extends Entity // @codeCoverageIgnoreEnd // }}} Autocode - public static function collectionCacheKey(LocalUser|Actor $actor, ?Actor $context = null) + public static function cacheKeys(LocalUser|Actor|int $actor, ?Actor $context = null): array { - return 'actor-' . $actor->getId() . '-langs' . (!\is_null($context) ? '-cxt-' . $context->getId() : ''); + $actor_id = \is_int($actor) ? $actor : $actor->getId(); + return [ + 'related-ids' => "actor-{$actor_id}-lang-related-ids", + 'actor-langs' => "actor-{$actor_id}-langs" . (!\is_null($context) ? "-cxt-{$context->getId()}" : ''), + ]; } public static function normalizeOrdering(LocalUser|Actor $actor) @@ -99,11 +104,11 @@ class ActorLanguage extends Entity /** * @return Language[] */ - public static function getActorLanguages(LocalUser|Actor $actor, ?Actor $context): array + public static function getActorLanguages(LocalUser|Actor $actor, ?Actor $context = null): array { $id = $context?->getId() ?? $actor->getId(); return Cache::getList( - self::collectionCacheKey($actor, context: $context), + self::cacheKeys($actor, context: $context)['actor-langs'], fn () => DB::dql( 'select l from actor_language al join language l with al.language_id = l.id where al.actor_id = :id order by al.ordering ASC', ['id' => $id], @@ -111,6 +116,30 @@ class ActorLanguage extends Entity ) ?: [Language::getByLocale(Common::config('site', 'language'))]; } + public static function getActorRelatedLanguagesIds(Actor $actor): array + { + return Cache::getList( + self::cacheKeys($actor)['related-ids'], + function () use ($actor) { + return F\map( + F\flat_map( + self::getActorLanguages($actor), + function ($language) { + if (str_contains($language->getLocale(), '_')) { + // Actor selected a language with a country, so don't attempt to provide alternatives + return $language; + } else { + // Actor selected a language without a country, so find all variants of the language + return DB::dql('select l from language l where l.locale like :locale', ['locale' => $language->getLocale() . '%']); + } + }, + ), + fn ($l) => $l->getId(), + ); + }, + ); + } + public static function schemaDef(): array { return [