From 839fa070c74ed91bc82bf7a665e312bac7f6e7b1 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Mon, 1 Nov 2021 19:43:23 +0000 Subject: [PATCH] [CORE][Posting] Default Posting language to site language, if the user hasn't selected one --- components/Posting/Posting.php | 18 +++++++--------- src/Entity/Actor.php | 39 ++++++++++++++++++++++------------ src/Security/Authenticator.php | 21 ++++++++++++------ src/Util/Common.php | 6 +++--- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index adef5e5f37..5c880d1349 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -67,6 +67,7 @@ class Posting extends Component return Event::next; } + $actor = $user->getActor(); $actor_id = $user->getId(); $to_tags = []; $tags = Cache::get( @@ -90,18 +91,15 @@ 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 + $request = $vars['request']; $form_params = [ - ['to', ChoiceType::class, ['label' => _m('To:'), 'multiple' => false, 'expanded' => false, 'choices' => $to_tags]], - ['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::getById($actor_id)->getPreferredLanguageChoice()]], + ['to', ChoiceType::class, ['label' => _m('To:'), 'multiple' => false, 'expanded' => false, 'choices' => $to_tags]], + ['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)]], ]; if (\count($available_content_types) > 1) { diff --git a/src/Entity/Actor.php b/src/Entity/Actor.php index 103e33fb2f..ce9d50461d 100644 --- a/src/Entity/Actor.php +++ b/src/Entity/Actor.php @@ -28,6 +28,7 @@ use App\Core\DB\DB; use App\Core\Entity; use App\Core\Router\Router; use App\Core\UserRoles; +use App\Util\Common; use App\Util\Exception\NicknameException; use App\Util\Nickname; use Component\Avatar\Avatar; @@ -283,11 +284,11 @@ class Actor extends Entity return Cache::get( 'followers-' . $this->id, function () { - return DB::dql( - 'select count(f) from App\Entity\Follow f where f.followed = :followed', - ['followed' => $this->id], - )[0][1] - 1; // Remove self follow - }, + return DB::dql( + 'select count(f) from App\Entity\Follow f where f.followed = :followed', + ['followed' => $this->id], + )[0][1] - 1; // Remove self follow + }, ); } @@ -296,11 +297,11 @@ class Actor extends Entity return Cache::get( 'followed-' . $this->id, function () { - return DB::dql( - 'select count(f) from App\Entity\Follow f where f.follower = :follower', - ['follower' => $this->id], - )[0][1] - 1; // Remove self follow - }, + return DB::dql( + 'select count(f) from App\Entity\Follow f where f.follower = :follower', + ['follower' => $this->id], + )[0][1] - 1; // Remove self follow + }, ); } @@ -362,10 +363,20 @@ EOF return $aliases; } - public function getPreferredLanguageChoice() + /** + * Get the most appropraite language for $this to use when + * referring to $context (a reply or a group, for instance) + * + * @return string the Language as a string (save space in cache) + */ + public function getPreferredLanguageChoice(?self $context = null): string { - $lang_id = $this->getPreferredLangId(); - return Cache::get("language-{$lang_id}", fn () => (string) DB::findOneBy('language', ['id' => $lang_id])); + $lang_id = $context?->getPreferredLangId() ?? $this->getPreferredLangId(); + if (\is_null($lang_id)) { + return Common::config('site', 'language'); + } + $key = 'actor-lang-' . $this->getId() . (!\is_null($context) ? '-' . $context->getId() : ''); + return Cache::get($key, fn () => (string) DB::findOneBy('language', ['id' => $lang_id])); } public static function schemaDef(): array @@ -385,7 +396,7 @@ EOF 'lon' => ['type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'], 'location_id' => ['type' => 'int', 'description' => 'location id if possible'], 'location_service' => ['type' => 'int', 'description' => 'service used to obtain location id'], - 'preferred_lang_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'one to many', 'description' => 'preferred language'], + 'preferred_lang_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'one to many', 'description' => 'preferred language'], 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], 'modified' => ['type' => 'timestamp', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'], ], diff --git a/src/Security/Authenticator.php b/src/Security/Authenticator.php index be8d437590..73d0b03464 100644 --- a/src/Security/Authenticator.php +++ b/src/Security/Authenticator.php @@ -31,7 +31,6 @@ use Exception; use Stringable; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; @@ -59,20 +58,24 @@ class Authenticator extends AbstractFormLoginAuthenticator public const LOGIN_ROUTE = 'security_login'; - private $urlGenerator; private $csrfTokenManager; - public function __construct(UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager) + public function __construct(CsrfTokenManagerInterface $csrfTokenManager) { - $this->urlGenerator = $urlGenerator; $this->csrfTokenManager = $csrfTokenManager; } + /** + * @return bool + */ public function supports(Request $request) { return self::LOGIN_ROUTE === $request->attributes->get('_route') && $request->isMethod('POST'); } + /** + * @return array + */ public function getCredentials(Request $request) { return [ @@ -84,6 +87,10 @@ class Authenticator extends AbstractFormLoginAuthenticator /** * Get a user given credentials and a CSRF token + * + * @param array $credentials result of self::getCredentials + * + * @return ?LocalUser */ public function getUser($credentials, UserProviderInterface $userProvider) { @@ -91,7 +98,7 @@ class Authenticator extends AbstractFormLoginAuthenticator if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } - + $user = null; try { if (filter_var($credentials['nickname_or_email'], \FILTER_VALIDATE_EMAIL) !== false) { $user = LocalUser::getByEmail($credentials['nickname_or_email']); @@ -107,12 +114,12 @@ class Authenticator extends AbstractFormLoginAuthenticator _m('Invalid login credentials.'), ); } - return $user; } /** - * @param LocalUser $user + * @param array $credentials result of self::getCredentials + * @param LocalUser $user */ public function checkCredentials($credentials, $user) { diff --git a/src/Util/Common.php b/src/Util/Common.php index 8a8cdd8619..92344f3f3d 100644 --- a/src/Util/Common.php +++ b/src/Util/Common.php @@ -79,11 +79,11 @@ abstract class Common */ public static function config(string $section, ?string $setting = null) { - if (!array_key_exists($section, self::$config)) { + if (!\array_key_exists($section, self::$config)) { return null; } else { if ($setting !== null) { - if (array_key_exists($setting, self::$config[$section])) { + if (\array_key_exists($setting, self::$config[$section])) { return self::$config[$section][$setting]; } else { return null; @@ -264,7 +264,7 @@ abstract class Common { return min( self::getPreferredPhpUploadLimit(), - self::config('attachments', 'file_quota') + self::config('attachments', 'file_quota'), ); }