在sonata管理包中管理一个到多个实体

Rez*_*asi 2 symfony sonata-admin


想象一下,您正在使用symfony2开发一个网站,它的管理面板使用Sonata Admin Bundle,当然想象您有一个名为Product的类,它拥有一些Images.Image也是一个类,您在Product中设置了一对多关系到Image类.因此,每个图像都归产品所有,因此您需要在Product Admin类中管理Image Admin.
所以你应该面对一些问题.你能告诉我怎么样?
1.删​​除产品对象时,将删除与该产品相关的所有图像.
2.当您在展示产品页面或添加新产品页面时,所有图像的图片显示在页面上.
(有没有使用奏鸣曲媒体包的解决方案呢?)
谢谢

我使用Document类处理Image上传:

FstQst\WebBundle\Entity\Document:
    type: entity
    table: null
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO

    fields:
        updated:        # changed when files are uploaded, to force preUpdate and postUpdate to fire
            type:         datetime
            nullable:     true

        format:
            type: string
            length: 25
            nullable: true


    lifecycleCallbacks:
        prePersist:   [ preUpload ]
        preUpdate:    [ preUpload ]
        postPersist:  [upload]
        postUpdate:   [upload]
        postRemove: [removeUpload]
Run Code Online (Sandbox Code Playgroud)

我有另一个类使用Document为图像添加一些功能:

FstQst\WebBundle\Entity\Post:
    type: entity
    table: null
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO

    fields:
        title:
            type: string
            length: 100
            nullable: true


    oneToOne:
        document:
            targetEntity: Document
            joinColumn:
                name: document_id
                referencedColumnName: id
            orphanRemoval: true

    manyToOne:
        site:
            targetEntity: VisitablePoint
            inversedBy: posts
            joinColumn:
                name: vPoint_id
                referencedColumnName: id

    lifecycleCallbacks: {  }
Run Code Online (Sandbox Code Playgroud)

还有一个名为VisitablePoint的类,它使用Post类:

FstQst\WebBundle\Entity\VisitablePoint:
    type: entity
    table: visitablePoint
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO


    oneToMany:
        posts:
            targetEntity: Post
            mappedBy: site
            orphanRemoval: true

    lifecycleCallbacks: {  }
Run Code Online (Sandbox Code Playgroud)

我将我的班级名称从Post更改为Image,从VisitablePoint更改为Product.现在我想要访问VisitablePoint管理员/显示页面时,我会看到Post对象的图片而不是他们的标题.当然还有管理/编辑页面.
这些是管理员类:

<?php

namespace FstQst\WebBundle\Admin;

use FstQst\WebBundle\Entity\Document;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class DocumentAdmin extends Admin
{
    /**
     * @param ListMapper $listMapper
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->add('id')
            ->add('updated')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                    'delete' => array(),
                )
            ))
        ;
    }

    /**
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {

        $formMapper
            ->add('file', 'file', $this->getFieldOptionForImagePreview())
        ;
    }


    /**
     * @param ShowMapper $showMapper
     */
    protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
            ->add('id')
            ->add('updated')
            ->add('format')
        ;
    }

    public function prePersist($image) {
        $this->manageFileUpload($image);
    }

    public function preUpdate($image) {
        $this->manageFileUpload($image);
    }

    protected function manageFileUpload(Document $image) {
        if ($image->getFile()) {
            $image->refreshUpdated();
        }
    }

    protected function getFieldOptionForImagePreview($maxSize = 200){
        if($this->hasParentFieldDescription()) { // this Admin is embedded
            // $getter will be something like 'getlogoImage'
            $getter = 'get' . $this->getParentFieldDescription()->getFieldName();

            // get hold of the parent object
            $parent = $this->getParentFieldDescription()->getAdmin()->getSubject();
            if ($parent) {
                $document = $parent->$getter();
            } else {
                $document = null;
            }
        } else {
            $document = $this->getSubject();
        }

        // use $fileFieldOptions so we can add other options to the field
        $fileFieldOptions = array('required' => false);
        if ($document && ($webPath = $document->getWebPath())) {
            // get the container so the full path to the image can be set
            $container = $this->getConfigurationPool()->getContainer();
            $fullPath = $container->get('request')->getBasePath().'/'.$webPath;
            //$fileFieldOptions['help'] = '<img src="/uploads/documents/10.png" class="admin-preview" style="max-height: 200px; max-width: 200px"/>';
            $fileFieldOptions['help'] = <<<START
<img src="$fullPath" style="max-height: {$maxSize}px; max-width: {$maxSize}px"/>
START;
        }

        return $fileFieldOptions;
    }

}
Run Code Online (Sandbox Code Playgroud)

<?php

namespace FstQst\WebBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class VisitablePointAdmin extends Admin
{

    /**
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('posts', 'sonata_type_model', array('multiple' => true, 'property' => 'title', 'label' => 'Image', 'required' => false))
        ;
    }

    /**
     * @param ShowMapper $showMapper
     */
    protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
             ->add('posts', 'sonata_type_collection', ['label' => 'Images',
                'required' => false, 'cascade_validation' => true,
                'by_reference' => false], ['edit' => 'inline', 'inline' => 'table'])
            ->end()
        ;
    }
}
Run Code Online (Sandbox Code Playgroud)

VBe*_*Bee 6

一对多的关系

1.删​​除产品对象时,将删除与该产品相关的所有图像.

您可以使用orphanRemoval ="true"轻松管理此类删除

<?php
class Product{
    [...]
    /**
     * @ORM\OneToMany(targetEntity="Event", mappedBy="day", orphanRemoval="true", cascade={"all"})
     */
    private $images;
    [...]
}
Run Code Online (Sandbox Code Playgroud)

在yml中,配置如下:

oneToMany:
  images:
    targetEntity: Image
    orphanRemoval: true
    mappedBy: product
Run Code Online (Sandbox Code Playgroud)

2.当您在展示产品页面或添加新产品页面时,所有图像的图片显示在页面上.

您必须在configureFormFields中使用sonata_type_collection或使用ProductAdmin类的configureShowFields方法:

<?php
class ProductAdmin{
    [...]
    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper
            ->with('tab_images')
                ->add('images', 'sonata_type_collection', array(
                    'required' => false,
                    'cascade_validation' => true,
                    'by_reference' => false,
                ), array(
                    'edit' => 'inline',
                    'inline' => 'table',
                ))
            ->end()
        ;
    }
    [...]
}
Run Code Online (Sandbox Code Playgroud)

然后为ImageAdmin提供上传文件所需的一切.您可能需要更改设置,因为我从个人项目中获取它,我不知道它是否完全适应您的需求.

在Sonata中显示图像

首先按如下方式配置ImageAdmin:

class ImageAdmin extends Admin
{
    [...]
    protected function configureShowFields(ShowMapper $showMapper) {
        $showMapper
            ->add('myImageAttr', 'image', array(
                'prefix' => '/',
            ))
        ;
    }
    [...]
    protected function configureListFields(ListMapper $listMapper) {
        $listMapper
            ->add('myImageAttr', 'image', array(
                'prefix' => '/',
                'width' => 100
            ))
        ;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后为list_image和show_image类型创建模板:

资源/视图/ CRUD/show_image.html.twig

{% extends 'SonataAdminBundle:CRUD:base_show_field.html.twig' %}
{% block field %}
    {% if value %}
        <img src="{% if field_description.options.prefix %}{{ field_description.options.prefix }}{% endif %}{{ value }}" />
    {% endif %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

资源/视图/ CRUD/list_image.html.twig

{% extends admin.getTemplate('base_list_field') %}

{% block field%}
{% spaceless %}
    {% set width = field_description.options.width is defined ? field_description.options.width : 50 %}
    {% set height = field_description.options.height is defined ? field_description.options.height : 50 %}
    {% if value %}
        <img src="{% if field_description.options.prefix is defined %}{{ field_description.options.prefix }}{% endif %}{{ value }}" 
            style="max-width:{{ width }}px; max-height:{{ height }}px;" />
    {% else %}
        <div class="no-image" style="width:{{ width }}px; height:{{ height }}px;"></div>
    {% endif %}
{% endspaceless %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

最后,将此配置添加到app/config/config.yml中

sonata_doctrine_orm_admin:
  templates:
    types:
      show:
        image: YourBundle:CRUD:show_image.html.twig
      list:
        image: YourBundle:CRUD:list_image.html.twig
Run Code Online (Sandbox Code Playgroud)

(http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/templates.html)