Symfony UX Autocomplete - choice_label with KnpLabs Translatable

rekjcdws  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(93)

自动完成选项标签不转换

平台是Symfony 6.3,带有UX Autocomplete 2.9

我的问题

我的问题:我有一个Symfony UX自动完成表单字段,choice_labels以翻译的形式存储在数据库中。我无法使choice_label转换工作。它总是默认为英语(我的默认语言环境)。
我有KnpLabs可翻译安装&工作.
我当前的设置:

  • FunctionProfile实体
  • FunctionProfileTranslation Entity ->包含翻译后的名称字段。
  • TrainingPickerType表单->包括FunctionProfileAutocompleteField
  • FunctionProfileAutocompleteField ->包含在TrainingPickerType中

只是为了确保,实体和表单(删除了代码中不必要的部分):

<?php

//App\Entity\FunctionProfile.php

namespace App\Entity;

use App\Repository\FunctionProfileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait;

#[ORM\Entity(repositoryClass: FunctionProfileRepository::class)]
class FunctionProfile implements TranslatableInterface
{
    use TranslatableTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

//etc.

    public function __toString(): string
    {
        return $this->translate(null, false)->getName();
    }

//etc.

字符串
它是朋友:

<?php

namespace App\Entity;

//App\Entity\FunctionProfileTranslation.php

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait;

#[ORM\Entity]
class FunctionProfileTranslation implements TranslationInterface
{
    use TranslationTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private $id;

    #[ORM\Column(length: 255)]
    private ?string $name = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }
}


现在,对于表单部分,这个主表单包括子表单字段,它没有做我想要它做的事情:

<?php

//App\Form\TrainingPickerType.php

namespace App\Form;

use App\Form\Field\FunctionProfileAutocompleteField;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class TrainingPickerType extends AbstractType
{
    private TranslatorInterface $translator;
    private UrlGeneratorInterface $router;

    public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $router)
    {
        $this->translator = $translator;
        $this->router = $router;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $locale = $options['locale'];
        $builder
            ->setAction($this->router->generate('app_api_get_training_pick_dialog'))
            ->add('functionProfile', FunctionProfileAutocompleteField::class, [
                'label' => $this->translator->trans('Function Profiles', locale: $locale),
                'attr' => ['class' => 'none', 'placeholder' => $this->translator->trans('Start typing or select an option...', locale: $locale),],
                'label_attr' => ['class' => 'block text-sm font-medium leading-6 text-white'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'locale' => null
        ]);
    }
}


上面的表单按照它应该的方式运行,语言环境被设置为它需要的任何地方,标签被很好地翻译,等等。
此包含的表单字段是问题所在:

<?php

namespace App\Form\Field;

use App\Entity\FunctionProfile;
use App\Repository\FunctionProfileRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
use Symfony\UX\Autocomplete\Form\ParentEntityAutocompleteType;

#[AsEntityAutocompleteField]
class FunctionProfileAutocompleteField extends AbstractType
{
    private RequestStack $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $request = $this->requestStack->getCurrentRequest();
        $query = $request?->query->get('query');
        $locale = $request ? $request->getLocale() : 'nl';
        
        $resolver->setDefaults([
            'class' => FunctionProfile::class,
            'multiple' => true,
            'choice_translation_domain' => true,
            'choice_label' => function (FunctionProfile $functionProfile) use ($locale) {
                $functionProfile->getTranslations();
                return $functionProfile->translate($locale)->getName();
            },
            'query_builder' => function(FunctionProfileRepository $functionProfileRepository) use ($locale, $query) {
                $qb = $functionProfileRepository->createQueryBuilder('functionProfile')
                    ->join('functionProfile.translations', 't', 'WITH', 't.locale = :locale')
                    ->setParameter('locale', $locale);

                if (!empty($query)) {
                    $qb->andWhere('t.name LIKE :search')
                        ->setParameter('search', '%' . $query . '%');
                }

                return $qb;
            },
        ]);
    }

    public function buildView(FormView|\Symfony\Component\Form\FormView $view, FormInterface|\Symfony\Component\Form\FormInterface $form, array $options): void
    {
        $view->vars['attr']['class'] = ''; // Remove any existing classes
    }

    public function getParent(): string
    {
        return ParentEntityAutocompleteType::class;
    }
}


当我输入一个查询时,搜索就会发生。将显示自动完成选项。但它们总是英文的,即使我手动设置不同的语言环境,如“nl”,结果仍然是一样的:所有choice_labels都是英文的。
任何指导或帮助你可能会提供超级欢迎!

我所尝试的

我已经搜索了KnpLabs可翻译文档的解决方案,但找不到任何解决方案。
我已验证(在表单字段之外),实体的翻译版本出现;作为例子;
x1c 0d1x的数据
当我运行时,整齐地返回Banana:

$test = $functionProfileRepository->findOneBy(["id" => 187]);
dd($test->translate('en')->getName());


当我奔跑的时候,

$test = $functionProfileRepository->findOneBy(["id" => 187]);
dd($test->translate('nl')->getName());


我尝试在一个单独的函数中检索choice_labels,然后将它们添加到choice_label选项中,但没有用。

public function getTranslatedLabel(FunctionProfile $functionProfile)
    {
        $request = $this->requestStack->getCurrentRequest();
        $locale = $request ? $request->getLocale() : 'nl';
        return $functionProfile->translate($locale)->getName();
    }


我现在也没什么主意了。
我知道https://github.com/a2lix/TranslationFormBundle,但我的同事表示除非绝对需要,否则不想使用它,并引用了早期版本的捆绑包的糟糕经验。但如果我们必须,我们会使用它。

hm2xizp9

hm2xizp91#

好吧,我是有点傻。我的$request->getLocale()还没有粘滞。一切都像它应该实现的那样工作这个EventSubscriber:https://symfony.com/doc/current/session.html#creating-a-localesubscriber

相关问题