diff --git a/components/Language/Controller/Language.php b/components/Language/Controller/Language.php index 4304ce1fdd..85c9a64178 100644 --- a/components/Language/Controller/Language.php +++ b/components/Language/Controller/Language.php @@ -28,8 +28,8 @@ use App\Core\Controller; use App\Core\DB\DB; use App\Core\Form; use function App\Core\I18n\_m; -use App\Entity\ActorLanguage; -use App\Entity\Language as LangEntity; +use Component\Language\Entity\ActorLanguage; +use Component\Language\Entity\Language as LangEntity; use App\Util\Common; use App\Util\Exception\NoLoggedInUser; use App\Util\Exception\RedirectException; diff --git a/src/Entity/ActorLanguage.php b/components/Language/Entity/ActorLanguage.php similarity index 98% rename from src/Entity/ActorLanguage.php rename to components/Language/Entity/ActorLanguage.php index 3c126d3006..0238f994ca 100644 --- a/src/Entity/ActorLanguage.php +++ b/components/Language/Entity/ActorLanguage.php @@ -21,11 +21,13 @@ declare(strict_types = 1); // }}} -namespace App\Entity; +namespace Component\Language\Entity; use App\Core\Cache; use App\Core\DB\DB; use App\Core\Entity; +use App\Entity\Actor; +use App\Entity\LocalUser; use App\Util\Common; use Functional as F; diff --git a/src/Entity/Language.php b/components/Language/Entity/Language.php similarity index 71% rename from src/Entity/Language.php rename to components/Language/Entity/Language.php index f8a6f2cc9c..762ccc4219 100644 --- a/src/Entity/Language.php +++ b/components/Language/Entity/Language.php @@ -1,6 +1,6 @@ F\reindex(DB::dql('select l from language l'), fn (self $l) => (string) $l->getId()), + key: (string)$id, + calculate_map: fn() => F\reindex(DB::dql('select l from language l'), fn(self $l) => (string)$l->getId()), ); } @@ -122,7 +125,7 @@ class Language extends Entity return Cache::getHashMapKey( 'languages', $locale, - calculate_map: fn () => F\reindex(DB::dql('select l from language l'), fn (self $l) => $l->getLocale()), + calculate_map: fn() => F\reindex(DB::dql('select l from language l'), fn(self $l) => $l->getLocale()), ); } @@ -135,10 +138,10 @@ class Language extends Entity { $langs = Cache::getHashMap( 'languages', - fn () => F\reindex(DB::dql('select l from language l'), fn (self $l) => $l->getLocale()), + fn() => F\reindex(DB::dql('select l from language l'), fn(self $l) => $l->getLocale()), ); - return array_merge(...F\map(array_values($langs), fn ($l) => $l->toChoiceFormat())); + return array_merge(...F\map(array_values($langs), fn($l) => $l->toChoiceFormat())); } public function toChoiceFormat(): array @@ -153,18 +156,18 @@ class Language extends Entity public static function getSortedLanguageChoices(?Actor $actor, ?Actor $context_actor, ?bool $use_short_display): array { $language_choices = self::getLanguageChoices(); - if (\is_null($actor)) { + if (is_null($actor)) { return [$language_choices, []]; } $preferred_language_choices = $actor->getPreferredLanguageChoices($context_actor); ksort($language_choices); if ($use_short_display ?? Common::config('posting', 'use_short_language_display')) { - $key = array_key_first($preferred_language_choices); - $locale = $preferred_language_choices[$key]; + $key = array_key_first($preferred_language_choices); + $language = $preferred_language_choices[$key]; unset($preferred_language_choices[$key], $language_choices[$key]); - $short_display = self::getByLocale($locale)->getShortDisplay(); - $preferred_language_choices[$short_display] = trim($locale); - $language_choices[$short_display] = trim($locale); + $short_display = $language->getShortDisplay(); + $preferred_language_choices[$short_display] = ($locale = $language->getLocale()); + $language_choices[$short_display] = $locale; } return [$language_choices, $preferred_language_choices]; } @@ -172,14 +175,14 @@ class Language extends Entity public static function schemaDef(): array { return [ - 'name' => 'language', + 'name' => 'language', 'description' => 'all known languages', - 'fields' => [ - 'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'], - 'locale' => ['type' => 'varchar', 'length' => 64, 'description' => 'The locale identifier for the language of a note. 2-leter-iso-language-code_4-leter-script-code_2-leter-iso-country-code, but kept longer in case we get a different format'], - 'long_display' => ['type' => 'varchar', 'length' => 64, 'description' => 'The long display string for the language, in english (translated later)'], - 'short_display' => ['type' => 'varchar', 'length' => 12, 'description' => 'The short display string for the language (used for the first option)'], - 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], + 'fields' => [ + 'id' => ['type' => 'serial', 'not null' => true, 'description' => 'unique identifier'], + 'locale' => ['type' => 'varchar', 'length' => 64, 'description' => 'The locale identifier for the language of a note. 2-leter-iso-language-code_4-leter-script-code_2-leter-iso-country-code, but kept longer in case we get a different format'], + 'long_display' => ['type' => 'varchar', 'length' => 64, 'description' => 'The long display string for the language, in english (translated later)'], + 'short_display' => ['type' => 'varchar', 'length' => 12, 'description' => 'The short display string for the language (used for the first option)'], + 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], ], 'primary key' => ['id'], 'unique keys' => [ diff --git a/components/Language/Language.php b/components/Language/Language.php index edbe4f109d..4155fbd478 100644 --- a/components/Language/Language.php +++ b/components/Language/Language.php @@ -25,11 +25,11 @@ use App\Core\Event; use App\Core\Modules\Component; use App\Core\Router\RouteLoader; use App\Entity\Actor; -use App\Entity\ActorLanguage; use App\Entity\Note; use App\Util\Formatting; use App\Util\Functional as GSF; use Component\Language\Controller as C; +use Component\Language\Entity\ActorLanguage; use Doctrine\Common\Collections\ExpressionBuilder; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; @@ -105,11 +105,11 @@ class Language extends Component public function onSearchQueryAddJoins(QueryBuilder &$note_qb, QueryBuilder &$actor_qb): bool { - $note_qb->leftJoin('App\Entity\Language', 'note_language', Expr\Join::WITH, 'note.language_id = note_language.id') - ->leftJoin('App\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'note.actor_id = actor_language.actor_id') - ->leftJoin('App\Entity\Language', 'note_actor_language', Expr\Join::WITH, 'note_actor_language.id = actor_language.language_id'); - $actor_qb->leftJoin('App\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'actor.id = actor_language.actor_id') - ->leftJoin('App\Entity\Language', 'language', Expr\Join::WITH, 'actor_language.language_id = language.id'); + $note_qb->leftJoin('Component\Language\Entity\Language', 'note_language', Expr\Join::WITH, 'note.language_id = note_language.id') + ->leftJoin('Component\Language\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'note.actor_id = actor_language.actor_id') + ->leftJoin('Component\Language\Entity\Language', 'note_actor_language', Expr\Join::WITH, 'note_actor_language.id = actor_language.language_id'); + $actor_qb->leftJoin('Component\Language\Entity\ActorLanguage', 'actor_language', Expr\Join::WITH, 'actor.id = actor_language.actor_id') + ->leftJoin('Component\Language\Entity\Language', 'language', Expr\Join::WITH, 'actor_language.language_id = language.id'); return Event::next; } } diff --git a/components/Posting/Posting.php b/components/Posting/Posting.php index 1c6c9a5ca7..12c7d15b83 100644 --- a/components/Posting/Posting.php +++ b/components/Posting/Posting.php @@ -35,7 +35,7 @@ use App\Core\Security; use App\Entity\Activity; use App\Entity\Actor; use App\Entity\GroupInbox; -use App\Entity\Language; +use Component\Language\Entity\Language; use App\Entity\Note; use App\Util\Common; use App\Util\Exception\ClientException; @@ -45,7 +45,6 @@ use App\Util\Exception\ServerException; use App\Util\Form\FormFields; use App\Util\Formatting; use Component\Attachment\Entity\ActorToAttachment; -use Component\Attachment\Entity\Attachment; use Component\Attachment\Entity\AttachmentToNote; use Component\Conversation\Conversation; use Functional as F; diff --git a/components/Tag/Tag.php b/components/Tag/Tag.php index 658ca75fd8..f718caad85 100644 --- a/components/Tag/Tag.php +++ b/components/Tag/Tag.php @@ -26,12 +26,12 @@ namespace Component\Tag; use App\Core\Cache; use App\Core\DB\DB; use App\Core\Event; +use Component\Language\Entity\Language; use function App\Core\I18n\_m; use App\Core\Modules\Component; use App\Core\Router\Router; use App\Entity\Actor; use App\Entity\ActorTag; -use App\Entity\Language; use App\Entity\Note; use App\Entity\NoteTag; use App\Util\Common; @@ -89,6 +89,7 @@ class Tag extends Component 'canonical' => $canonical_tag, 'note_id' => $note->getId(), 'use_canonical' => $extra_args['tag_use_canonical'] ?? false, + 'language_id' => $lang_id, ])); Cache::pushList("tag-{$canonical_tag}", $note); foreach (self::cacheKeys($canonical_tag) as $key) { diff --git a/plugins/ActivityPub/Util/Model/Note.php b/plugins/ActivityPub/Util/Model/Note.php index c5688c2d07..a3602599a0 100644 --- a/plugins/ActivityPub/Util/Model/Note.php +++ b/plugins/ActivityPub/Util/Model/Note.php @@ -39,10 +39,10 @@ use App\Core\DB\DB; use App\Core\Event; use App\Core\GSFile; use App\Core\HTTPClient; +use Component\Language\Entity\Language; use function App\Core\I18n\_m; use App\Core\Log; use App\Core\Router\Router; -use App\Entity\Language; use App\Entity\Note as GSNote; use App\Entity\NoteTag; use App\Util\Common; @@ -225,6 +225,7 @@ class Note extends Model 'canonical' => $canonical_tag, 'note_id' => $obj->getId(), 'use_canonical' => $ap_tag->get('canonical') ?? false, + 'language_id' => $lang_id, ])); Cache::pushList("tag-{$canonical_tag}", $obj); foreach (Tag::cacheKeys($canonical_tag) as $key) { diff --git a/plugins/RepeatNote/RepeatNote.php b/plugins/RepeatNote/RepeatNote.php index b5236c424a..74507de3b5 100644 --- a/plugins/RepeatNote/RepeatNote.php +++ b/plugins/RepeatNote/RepeatNote.php @@ -29,7 +29,7 @@ use App\Core\Router\RouteLoader; use App\Core\Router\Router; use App\Entity\Activity; use App\Entity\Actor; -use App\Entity\Language; +use Component\Language\Entity\Language; use App\Entity\Note; use App\Util\Common; use App\Util\Exception\DuplicateFoundException; diff --git a/plugins/TagBasedFiltering/Controller/AddBlocked.php b/plugins/TagBasedFiltering/Controller/AddBlocked.php index e8bc71fedd..f39f272e1d 100644 --- a/plugins/TagBasedFiltering/Controller/AddBlocked.php +++ b/plugins/TagBasedFiltering/Controller/AddBlocked.php @@ -31,7 +31,7 @@ use function App\Core\I18n\_m; use App\Entity\Actor; use App\Entity\ActorTag; use App\Entity\ActorTagBlock; -use App\Entity\Language; +use Component\Language\Entity\Language; use App\Entity\Note; use App\Entity\NoteTag; use App\Entity\NoteTagBlock; diff --git a/src/Command/PopulateInitialValuesCommand.php b/src/Command/PopulateInitialValuesCommand.php index d4ee7d9c74..0674886ce1 100644 --- a/src/Command/PopulateInitialValuesCommand.php +++ b/src/Command/PopulateInitialValuesCommand.php @@ -33,7 +33,7 @@ declare(strict_types = 1); namespace App\Command; use App\Core\DB\DB; -use App\Entity\Language; +use Component\Language\Entity\Language; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; diff --git a/src/Entity/Actor.php b/src/Entity/Actor.php index b19c4404ee..cfbf91257b 100644 --- a/src/Entity/Actor.php +++ b/src/Entity/Actor.php @@ -35,6 +35,8 @@ use App\Util\Exception\NotFoundException; use App\Util\Formatting; use App\Util\Nickname; use Component\Avatar\Avatar; +use Component\Language\Entity\ActorLanguage; +use Component\Language\Entity\Language; use DateTimeInterface; use Functional as F; diff --git a/src/Entity/Note.php b/src/Entity/Note.php index 5da7be4e67..2011027ef6 100644 --- a/src/Entity/Note.php +++ b/src/Entity/Note.php @@ -32,6 +32,7 @@ use App\Core\VisibilityScope; use App\Util\Formatting; use Component\Avatar\Avatar; use Component\Conversation\Entity\Conversation; +use Component\Language\Entity\Language; use DateTimeInterface; /** diff --git a/src/Entity/NoteTag.php b/src/Entity/NoteTag.php index 29f85b8bd0..7593cdd821 100644 --- a/src/Entity/NoteTag.php +++ b/src/Entity/NoteTag.php @@ -50,6 +50,7 @@ class NoteTag extends Entity private string $canonical; private int $note_id; private bool $use_canonical; + private int $language_id; private DateTimeInterface $created; public function setTag(string $tag): self @@ -96,6 +97,17 @@ class NoteTag extends Entity return $this->use_canonical; } + public function setLanguageId(int $language_id): NoteTag + { + $this->language_id = $language_id; + return $this; + } + + public function getLanguageId(): int + { + return $this->language_id; + } + public function setCreated(DateTimeInterface $created): self { $this->created = $created; @@ -142,6 +154,7 @@ class NoteTag extends Entity 'canonical' => ['type' => 'varchar', 'length' => Tag::MAX_TAG_LENGTH, 'not null' => true, 'description' => 'ascii slug of tag'], 'note_id' => ['type' => 'int', 'foreign key' => true, 'target' => 'Note.id', 'multiplicity' => 'one to one', 'not null' => true, 'description' => 'foreign key to tagged note'], 'use_canonical' => ['type' => 'bool', 'not null' => true, 'description' => 'whether the user wanted to use canonical tags in this note. Separate for blocks'], + 'language_id' => ['type' => 'int', 'not null' => false, 'foreign key' => true, 'target' => 'Language.id', 'multiplicity' => 'many to many', 'description' => 'the language this entry refers to'], 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'], ], 'primary key' => ['tag', 'note_id'], diff --git a/src/Util/Form/FormFields.php b/src/Util/Form/FormFields.php index 816ed03f03..7f2eeabb88 100644 --- a/src/Util/Form/FormFields.php +++ b/src/Util/Form/FormFields.php @@ -6,7 +6,7 @@ namespace App\Util\Form; use function App\Core\I18n\_m; use App\Entity\Actor; -use App\Entity\Language; +use Component\Language\Entity\Language; use App\Util\Common; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\PasswordType;