我花了很长时间才能获得正确的标题,而我还没有写下这个问题:/
这里是:我的菜单是从实体加载的。为了让用户将菜单翻译成多种语言,我创建了一个Menu
实体和一个LocalizedMenu
实体,该实体通过Menu
关联与ManyToOne
相关联。
在this short guide之后,我将该关联与LocalizedMenu->locale
字段编入索引。这确保了数据库中每个语言环境只有一个LocalizedMenu
,并且该原则会覆盖现有的语言环境。
这是什么看起来像:
/**
* @ORM\Entity(repositoryClass="App\Repository\MenuRepository")
*/
class Menu
{
/**
* @Groups({"menu"})
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* References translated menus.
* @Groups({"localized_menus"})
*
* @ORM\OneToMany(
* targetEntity="LocalizedMenu"
* ,mappedBy="parentMenu"
* ,indexBy="locale"
* ,cascade={"persist", "remove"}
* )
* @ORM\OrderBy({"locale" = "ASC"})
*/
private $localizedMenus;
// ...
public function getLocalizedMenu($locale) {
if (!isset($this->localizedMenus[$locale])) {
return new LocalizedMenu($locale, $this);
}
return $this->localizedMenus[$locale];
}
public function addLocalizedMenu($localizedMenu): self
{
$this->localizedMenus[$localizedMenu->getLocale()] = $localizedMenu;
return $this;
}
}
LocalizedMenu
是一个保存用户翻译的菜单字段的实体:
/**
* @ORM\Entity(repositoryClass="App\Repository\LocalizedMenuRepository")
*/
class LocalizedMenu
{
public function __construct($locale, $menu) {
$this->locale = $locale;
$this->parentMenu = $menu;
$this->parentMenu->addLocalizedMenu($this);
}
// region FIELDS
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Groups({"localized_menu", "localized_menus"})
* @var $locale string
* @ORM\Column(
* type = "string"
* ,unique = true
* )
*/
private $locale = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORM\Column(
* type = "string",
* length = 75
* )
*/
private $title = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @var $description string Extra description for this menu item
* @ORM\Column(
* type = "text",
* name = "description"
* )
*/
private $description = "";
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORM\Column(
* type = "datetime",
* name = "creation_date"
* )
* @Assert\DateTime()
*/
private $creationDate;
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORM\Column(
* type = "datetime",
* name = "edit_date"
* )
* @Assert\DateTime()
*/
private $editDate;
/**
* @Groups({"localized_menu", "localized_menus"})
* @ORM\Column(type="text")
* @Assert\NotBlank(
* message = "Een menu item is een pagina die inhoud nodig heeft, vergeet dit niet"
* )
*/
private $content = "";
/**
* @var $parentMenu Menu Parent menu for this localized menu
*
* @Groups({"localized_menu", "localized_parent_menu"})
* @ORM\ManyToOne(
* targetEntity="Menu",
* inversedBy="localizedMenus"
* )
*/
private $parentMenu;
}
为了将这一切带给用户进行编辑,我创建了一个MenyType
表单:
$builder
->add('localizedMenus', CollectionType::class, array(
'entry_type' => LocalizedMenuType::class,
"entry_options" => [
"choice_locale" => $options["choice_locale"]
],
'allow_add' => true,
'allow_delete' => true,
'required' => false
))
和LocalizedMenuType
形式:
$builder
->add('title', TextType::class, array(
'label' => 'Titel',
'trim' => true
))
->add('description', TextareaType::class, array(
'label' => 'Omschrijving',
'trim' => true
))
->add('content', TextareaType::class, array(
'label' => 'Inhoud',
'trim' => true,
'attr' => array('class' => 'tinymce'),
'data' => " "
))
->add('locale', LocaleType::class, array(
"choice_translation_locale" => $options["choice_locale"]
))
;
我“认为”这个逻辑是正确的,但在使用javascript创建新的LocalizedMenu
表单后,我收到此错误:
函数App \ Entity \ LocalizedMenu :: __ construct()的参数太少,0在第136行的/Users/robbievercammen/Projects/web/base/vendor/symfony/form/Extension/Core/Type/FormType.php中传递2预期
如何让我的表单与我的逻辑优雅地工作?
编辑 - 真正的问题
错误消息不是真正的错误。正如我之前所说,如果删除构造函数参数,它会将记录保存到数据库中。即让教条使用该关联将新的LocalizedMenu
记录与Menu
记录相关联。这就是它在数据库中的样子:
Menu
|id| //...
| 7| //...
LocalizedMenu
| id | locale | title | description | creation_date | edit_date
| content | parent_menu_id |
----
| 4 | nl | Contact | Contact | 2019-02-21 14:02:47 | 2019-02-21 14:02:47 |
Contact | NULL |
问题是LocalizedMenu -> parent_menu_id
是NULL。出于某种原因,我的设置不会为父菜单生成ID。下次从数据库中获取菜单时,$menu->getLocalizedMenus()
返回一个空数组,因为它们没有正确关联。
在我提到的guide之后,这看起来似乎是我能用$localizedMenu -> locale
告诉学说索引的唯一方法
你的LocalizedMenu
构造函数需要两个参数--$locale
和$menu
。当Symfony为您新提交的数据实例化新的LocalizedMenu
实例时,它会直接填充new LocalizedMenu()
来填充其数据。
如果需要自定义如何为表单中的新/动态内容创建对象(例如,当您有构造函数参数时),则必须在empty_data
类上设置LocalizedMenuType
选项。
有关更多信息,请参阅https://symfony.com/doc/current/form/use_empty_data.html。
你的一个LocalizedMenu
构造函数参数是一个菜单实例。此菜单实例需要作为必需选项传递到LocalizedMenuType
。
class LocalizedMenuType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired('menu');
$resolver->setAllowedTypes('menu', Menu::class);
$resolver->setDefault('empty_data', function (Options $options) {
return new LocalizedMenu($options['choice_locale'], $options['menu']);
});
}
}