gpt4 book ai didi

symfony - 如何在 Sonata Media Bundle 中实现多对多关系

转载 作者:行者123 更新时间:2023-12-03 12:45:36 25 4
gpt4 key购买 nike

我正在尝试将 SonataMediaBundle 与另一个实体相关联:产品 具有多对多关系。

架构和关系创建得很好。

但是,当我编辑或创建新产品时,我尝试添加一个按钮,我可以在其中通过媒体库搜索媒体文件,并添加一个按钮来上传新文件。

对于 OneToMany 关系,这很容易在 Admin\ProductAdmin::configureFormFields 中完成。通过增加:

->add('image', 'sonata_type_model_list', array(
'required' => false
), array(
'link_parameters' => array(
'context' => 'default',
'provider' => 'sonata.media.provider.image'
)
))

所以我得到了与 SonataMediaBundle 画廊中已经使用的相同的 3 个图标(从库中添加、上传和删除)


在多对多关系上,这是不可能的!因为每次我选择一种媒体时,它都会取代之前的媒体。所以我不能选择多种媒体类型。

我想过使用与画廊相同的方式( galleryHasMedia)
->add('galleryHasMedias', 'sonata_type_collection', array(
'by_reference' => false
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => $context)
))

然而,它真的很复杂。
如何通过多对多关系在另一个实体上选择或上传多个媒体文件?

最佳答案

我和你有同样的问题,但我已经解决了。

首先,您可能希望选择一对多/多对一关系(使用中间实体)而不是多对多关系。为什么?因为这允许额外的列,例如 position柱子。这样,您可以以任何您想要的方式重新排序图像。在多对多关系中,链接表只有两列:关联表的 id。

来自 Doctrine documentation :

(...) frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.



所以我将此添加到我的产品映射文件中:(如您所见,我使用 YAML 作为我的配置文件格式)
oneToMany:
images:
targetEntity: MyBundle\Entity\ProductImage
mappedBy: product
orderBy:
position: ASC

我创建了一个新的 ProductImage 映射文件:
MyBundle\Entity\ProductImage:
type: entity
table: product_images
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
position:
type: integer
manyToOne:
product:
targetEntity: MyBundle\Entity\Product
inversedBy: images
image:
targetEntity: Application\Sonata\MediaBundle\Entity\Media

使用命令行( php app/console doctrine:generate:entities MyBundle )我创建/更新了相应的实体( ProductProductImage )。

接下来,我创建/更新了 Admin 类。产品管理员.php:
class ProductAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
// define other form fields
->add('images', 'sonata_type_collection', array(
'required' => false
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
))
;
}

ProductImageAdmin.php:
class ProductImageAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('image', 'sonata_type_model_list', array(
'required' => false
), array(
'link_parameters' => array(
'context' => 'product_image'
)
))
->add('position', 'hidden')
;
}

不要忘记将它们都添加为服务。如果您不想在仪表板上显示 ProductImage 表单的链接,请添加 show_in_dashboard: false标签。 (您如何执行此操作取决于您使用的配置格式(yaml/xml/php))

在此之后,我的管理表单正常工作,但是我在尝试保存产品时仍然遇到了一些问题。我必须执行以下步骤才能解决所有问题:

首先,我必须为 Product 实体配置级联持久化操作。同样,如何执行此操作取决于您的配置格式。我正在使用 yaml,所以在 images一对多的关系,我添加了级联属性:
oneToMany:
images:
targetEntity: MyBundle\Entity\ProductImage
mappedBy: product
orderBy:
position: ASC
cascade: ["persist"]

这让它工作了(或者我认为),但我注意到 product_id在数据库中设置为 NULL .我通过添加 prePersist() 解决了这个问题和 preUpdate() ProductAdmin 的方法类(class):
public function prePersist($object)
{
foreach ($object->getImages() as $image) {
$image->setProduct($object);
}
}

public function preUpdate($object)
{
foreach ($object->getImages() as $image) {
$image->setProduct($object);
}
}

...并在 addImages() 中添加了一行 Product 的方法实体:
public function addImage(\MyBundle\Entity\ProductImage $images)
{
$images->setProduct($this);
$this->images[] = $images;

return $this;
}

这对我有用,现在我可以在我的产品中添加、更改、重新排序、删除等图像。

关于symfony - 如何在 Sonata Media Bundle 中实现多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11612966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com