From 019ad794d10252cd38847ab427db44157933714e Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Tue, 2 Nov 2021 11:11:51 +0000 Subject: [PATCH] [Posting] Add dropdown with language choice, with preferred choice according to user choice and context (group, etc) --- components/Posting/Posting.php | 10 +++++++--- src/Entity/Actor.php | 28 +++++++++++++++------------- src/Entity/Language.php | 16 ++++++++++++++-- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index 5c880d1349..7bf8e41c43 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -35,6 +35,7 @@ use App\Entity\Actor; use App\Entity\ActorToAttachment; use App\Entity\Attachment; use App\Entity\AttachmentToNote; +use App\Entity\Language; use App\Entity\Note; use App\Util\Common; use App\Util\Exception\ClientException; @@ -44,7 +45,6 @@ use App\Util\Exception\ServerException; use App\Util\Formatting; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\FileType; -use Symfony\Component\Form\Extension\Core\Type\LocaleType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\HttpFoundation\File\Exception\FormSizeFileException; @@ -91,7 +91,11 @@ class Posting extends Component ]; Event::handle('PostingAvailableContentTypes', [&$available_content_types]); - $context_actor = null; // This is where we'd plug in the group in which the actor is posting, or whom they're replying to + $context_actor = null; // This is where we'd plug in the group in which the actor is posting, or whom they're replying to + $preferred_language_choices = $actor->getPreferredLanguageChoices($context_actor); + $language_choices = Language::getLanguageChoices(); + + // TODO short display $request = $vars['request']; $form_params = [ @@ -99,7 +103,7 @@ class Posting extends Component ['visibility', ChoiceType::class, ['label' => _m('Visibility:'), 'multiple' => false, 'expanded' => false, 'data' => 'public', 'choices' => [_m('Public') => 'public', _m('Instance') => 'instance', _m('Private') => 'private']]], ['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)], 'constraints' => [new Length(['max' => Common::config('site', 'text_limit')])]]], ['attachments', FileType::class, ['label' => _m('Attachments:'), 'multiple' => true, 'required' => false, 'invalid_message' => _m('Attachment not valid.')]], - ['language', LocaleType::class, ['label' => _m('Note language:'), 'multiple' => false, 'preferred_choices' => $actor->getPreferredLanguageChoice($context_actor)]], + ['language', ChoiceType::class, ['label' => _m('Note language:'), 'preferred_choices' => $preferred_language_choices, 'choices' => $language_choices, 'required' => true, 'multiple' => false]], ]; if (\count($available_content_types) > 1) { diff --git a/src/Entity/Actor.php b/src/Entity/Actor.php index 27fb8934bc..f9e6b0fda5 100644 --- a/src/Entity/Actor.php +++ b/src/Entity/Actor.php @@ -315,15 +315,15 @@ class Actor extends Entity return Cache::get( 'relative-nickname-' . $nickname . '-' . $this->getId(), fn () => DB::dql( - <<<'EOF' - select a from actor a where - a.id in (select fa.followed from follow fa join actor aa with fa.followed = aa.id where fa.follower = :actor_id and aa.nickname = :nickname) or - a.id in (select fb.follower from follow fb join actor ab with fb.follower = ab.id where fb.followed = :actor_id and ab.nickname = :nickname) or - a.nickname = :nickname - EOF, - ['nickname' => $nickname, 'actor_id' => $this->getId()], - ['limit' => 1], - )[0] ?? null, + <<<'EOF' + select a from actor a where + a.id in (select fa.followed from follow fa join actor aa with fa.followed = aa.id where fa.follower = :actor_id and aa.nickname = :nickname) or + a.id in (select fb.follower from follow fb join actor ab with fb.follower = ab.id where fb.followed = :actor_id and ab.nickname = :nickname) or + a.nickname = :nickname + EOF, + ['nickname' => $nickname, 'actor_id' => $this->getId()], + ['limit' => 1], + )[0] ?? null, ); } @@ -363,10 +363,12 @@ class Actor extends Entity $id = $context?->getId() ?? $this->getId(); return Cache::get( 'actor-' . $this->getId() . '-langs' . (!\is_null($context) ? '-' . $context->getId() : ''), - 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.order ASC', - ['id' => $id], - ) ?: [DB::findOneBy('language', ['locale' => Common::config('site', 'language')])], + fn () => array_merge( // TODO replace with F\transform + ...F\map(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.order ASC', + ['id' => $id], + ), fn ($l) => $l->toChoiceFormat()), + ) ?: DB::findOneBy('language', ['locale' => Common::config('site', 'language')])->toChoiceFormat(), ); } diff --git a/src/Entity/Language.php b/src/Entity/Language.php index 7d31e0d654..0642aa99ea 100644 --- a/src/Entity/Language.php +++ b/src/Entity/Language.php @@ -23,8 +23,12 @@ declare(strict_types = 1); namespace App\Entity; +use App\Core\Cache; +use App\Core\DB\DB; use App\Core\Entity; +use function App\Core\I18n\_m; use DateTimeInterface; +use Functional as F; /** * Entity for languages @@ -103,9 +107,17 @@ class Language extends Entity // @codeCoverageIgnoreEnd // }}} Autocode - public function __toString() + public static function getLanguageChoices(): array { - return $this->getLongDisplay(); + return Cache::getList( + 'languages', // TODO replace with F\transform + fn () => array_merge(...F\map(DB::dql('select l from language l'), fn ($e) => $e->toChoiceFormat())), + ); + } + + public function toChoiceFormat(): array + { + return [_m($this->getLongDisplay()) => $this->getShortDisplay()]; } public static function schemaDef(): array