[COMPONENT][Language][ENTITY][ActorLanguage] Refactor cache keys in ActorLanguage. Add ActorLangauge::getActorRelatedLanguagesIds and use it in note filtering in the Language component

This commit is contained in:
Hugo Sales 2021-12-10 10:19:01 +00:00
parent 5dd9e5a3d7
commit 33fba0d970
No known key found for this signature in database
GPG Key ID: 7D0C7EAFC9D835A0
3 changed files with 37 additions and 15 deletions

View File

@ -21,10 +21,10 @@ declare(strict_types = 1);
namespace Component\Language; namespace Component\Language;
use App\Core\DB\DB;
use App\Core\Event; use App\Core\Event;
use App\Core\Modules\Component; use App\Core\Modules\Component;
use App\Entity\Actor; use App\Entity\Actor;
use App\Entity\ActorLanguage;
use App\Entity\Note; use App\Entity\Note;
use Functional as F; use Functional as F;
@ -32,16 +32,9 @@ class Language extends Component
{ {
public function onFilterNoteList(Actor $actor, array &$notes) 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 = F\select(
$notes, $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; return Event::next;

View File

@ -215,9 +215,9 @@ class UserPanel extends Controller
} }
} }
Cache::delete(ActorLanguage::collectionCacheKey($user)); Cache::delete(ActorLanguage::cacheKeys($user)['actor-langs']);
DB::flush();
ActorLanguage::normalizeOrdering($user); // In case the user doesn't submit the other page ActorLanguage::normalizeOrdering($user); // In case the user doesn't submit the other page
DB::flush();
unset($data['languages']); unset($data['languages']);
throw new RedirectException('settings_sort_languages', ['_fragment' => null]); // TODO doesn't clear fragment throw new RedirectException('settings_sort_languages', ['_fragment' => null]); // TODO doesn't clear fragment

View File

@ -27,6 +27,7 @@ use App\Core\Cache;
use App\Core\DB\DB; use App\Core\DB\DB;
use App\Core\Entity; use App\Core\Entity;
use App\Util\Common; use App\Util\Common;
use Functional as F;
/** /**
* Entity for actor languages * Entity for actor languages
@ -81,9 +82,13 @@ class ActorLanguage extends Entity
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
// }}} Autocode // }}} 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) public static function normalizeOrdering(LocalUser|Actor $actor)
@ -99,11 +104,11 @@ class ActorLanguage extends Entity
/** /**
* @return Language[] * @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(); $id = $context?->getId() ?? $actor->getId();
return Cache::getList( return Cache::getList(
self::collectionCacheKey($actor, context: $context), self::cacheKeys($actor, context: $context)['actor-langs'],
fn () => DB::dql( 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', '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], ['id' => $id],
@ -111,6 +116,30 @@ class ActorLanguage extends Entity
) ?: [Language::getByLocale(Common::config('site', 'language'))]; ) ?: [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 public static function schemaDef(): array
{ {
return [ return [