Sonata Admin Image Field

时间:2017-08-08 10:43:48

标签: symfony sonata-admin sonata-media-bundle

我正在使用Sonata Admin后端,我想向我的用户实体添加新图片字段,这是一个虚拟角色。由于我已使用SonataMediaBundle,因此我遵循了本教程:https://sonata-project.org/blog/2013/10/11/mediabundle-mediatype-improved

这是我的实体配置:

/**
 * @var \Application\Sonata\MediaBundle\Entity\Media
 *
 * @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media", cascade={"all"}, fetch="LAZY")
 * @ORM\JoinColumn(name="avatar_id", referencedColumnName="id")
 */
protected $avatar;

不幸的是我遇到了很多问题:

  1. 在我的后端,未显示预览: enter image description here
  2. 如果我删除了图库中的媒体,则在编辑用户时会收到此错误:Entity of type 'Application\Sonata\MediaBundle\Entity\Media' for IDs id(6) was not found
  3. 客户端无法使用生成的API(使用FOSRestBundle生成):
  4. "avatar": {
            "provider_metadata": {
                "filename": "Test.png"
            },
            "name": "Test.png",
            "description": null,
            "enabled": false,
            "provider_name": "sonata.media.provider.image",
            "provider_status": 1,
            "provider_reference": "325564b03489a6473e7c9def01dc58bab611eccb.png",
            "width": 1430,
            "height": 321,
            "length": null,
            "copyright": null,
            "author_name": null,
            "context": "default",
            "cdn_is_flushable": null,
            "cdn_flush_at": null,
            "cdn_status": null,
            "updated_at": "2017-08-08T12:31:19+02:00",
            "created_at": "2017-08-08T12:31:19+02:00",
            "content_type": "image/png",
            "size": 24978,
            "id": 7
        }
    

    非常感谢。

1 个答案:

答案 0 :(得分:2)

我解决了所有3个问题!我把解决方案提供给所有遇到同样困难的人。

  
      
  1. 在我的后端,未显示预览:
  2.   

正如here所述,我必须在我的config.yml文件中添加自定义表单小部件:

twig:
    # Sonata form themes
    form_themes:
        - 'SonataMediaBundle:Form:media_widgets.html.twig'

在我的UserAdmin

->with('Profile')
    ->add('avatar', 'sonata_media_type', array(
        'provider' => 'sonata.media.provider.image',
        'context'  => 'default',
    ))
->end()

现在将显示预览:)

  
      
  1. 如果我删除了库中的媒体,则在编辑用户时会收到此错误:类型实体   ID为ID(6)的'Application \ Sonata \ MediaBundle \ Entity \ Media'不是   结果
  2.   

正如here所述,我需要在我的实体上添加onDelete="SET NULL"

/**
 * @var \Application\Sonata\MediaBundle\Entity\Media
 *
 * @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
 * @ORM\JoinColumn(name="avatar_id", referencedColumnName="id", onDelete="SET NULL")
 */
protected $avatar;
  
      
  1. 客户端无法使用生成的API(使用FOSRestBundle生成):
  2.   

这个非常棘手,但我能够从this帖子开始实现自定义JMS处理程序。

我偷看了SonataMediaBundle源代码,我找到了这个代码段:

/**
 * Returns media urls for each format.
 *
 * @ApiDoc(
 *  requirements={
 *      {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="media id"}
 *  },
 *  statusCodes={
 *      200="Returned when successful",
 *      404="Returned when media is not found"
 *  }
 * )
 *
 * @param $id
 *
 * @return array
 */
public function getMediumFormatsAction($id)
{
    $media = $this->getMedium($id);

    $formats = array(MediaProviderInterface::FORMAT_REFERENCE);
    $formats = array_merge($formats, array_keys($this->mediaPool->getFormatNamesByContext($media->getContext())));

    $provider = $this->mediaPool->getProvider($media->getProviderName());

    $properties = array();
    foreach ($formats as $format) {
        $properties[$format]['url'] = $provider->generatePublicUrl($media, $format);
        $properties[$format]['properties'] = $provider->getHelperProperties($media, $format);
    }

    return $properties;
}

所以我将它包含在我的源代码中,完整的处理程序如下:

<?php

namespace AppBundle\Serializer;

use Application\Sonata\MediaBundle\Entity\Media;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use Sonata\MediaBundle\Provider\MediaProviderInterface;

class MediaHandler implements SubscribingHandlerInterface
{
    private $mediaPool;

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

    public static function getSubscribingMethods()
    {
        return array(
            array(
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format'    => 'json',
                'type'      => 'Application\Sonata\MediaBundle\Entity\Media',
                'method'    => 'serializeToJson',
            ),
        );
    }

    public function serializeToJson(JsonSerializationVisitor $visitor, Media $media, array $type, Context $context)
    {
        $formats = array(MediaProviderInterface::FORMAT_REFERENCE);
        $formats = array_merge($formats, array_keys($this->mediaPool->getFormatNamesByContext($media->getContext())));

        $provider = $this->mediaPool->getProvider($media->getProviderName());

        $properties = array();
        foreach ($formats as $format) {
            $properties[$format]['url']        = $provider->generatePublicUrl($media, $format);
            $properties[$format]['properties'] = $provider->getHelperProperties($media, $format);
        }

        return $properties;
    }
}

服务设置:

app.serializer.media:
    class: AppBundle\Serializer\MediaHandler
    arguments:
      - '@sonata.media.pool'
    tags:
        - { name: jms_serializer.subscribing_handler }

就是这样!