奏鸣曲管理图像字段

Sonata Admin Image Field

我正在使用 Sonata Admin back-end,我想向我的用户实体添加一个新图像字段,这是一个化身。由于我已经在使用 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. 在我的 back-end 中没有显示预览:
  2. 如果我删除图库中的媒体,我在编辑用户时收到此错误:Entity of type 'Application\Sonata\MediaBundle\Entity\Media' for IDs id(6) was not found
  3. 客户端无法使用结果 API(使用 FOSRestBundle 生成):
"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
    }

我解决了所有的 3 个问题!我把我的解决方案放在这里给所有有同样困难的人。

  1. In my back-end the preview is not shown:

如前所述 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. If I delete the media in the gallery I receive this error when editing the user: Entity of type 'Application\Sonata\MediaBundle\Entity\Media' for IDs id(6) was not found

如前所述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. The resulting API (generated with FOSRestBundle) is unusable by the client:

这个非常棘手,但我能够从 this post.

开始实施自定义 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 }

仅此而已!