Symfony2 覆盖 Sonata 媒体图像提供程序。(将接口传递给构造函数)

Posted

技术标签:

【中文标题】Symfony2 覆盖 Sonata 媒体图像提供程序。(将接口传递给构造函数)【英文标题】:Symfony2 Overriding Sonata media Image provider.(Passing interface to constructor) 【发布时间】:2016-03-27 06:48:43 【问题描述】:

我想覆盖 SonataMediaBundle 的图像提供程序,但是,当我覆盖它时,调用构造函数时出现错误:

Catchable Fatal Error: Argument 8 passed to Application\Sonata\MediaBundle\Provider\NewImageProvider::__construct() must be an instance of Imagine\Image\ImagineInterface, none given

这是构造函数:

/**
 * @param string                                                $name
 * @param \Gaufrette\Filesystem                                 $filesystem
 * @param \Sonata\MediaBundle\CDN\CDNInterface                  $cdn
 * @param \Sonata\MediaBundle\Generator\GeneratorInterface      $pathGenerator
 * @param \Sonata\MediaBundle\Thumbnail\ThumbnailInterface      $thumbnail
 * @param array                                                 $allowedExtensions
 * @param array                                                 $allowedMimeTypes
 * @param \Imagine\Image\ImagineInterface                       $adapter
 * @param \Sonata\MediaBundle\Metadata\MetadataBuilderInterface $metadata
 */
public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, array $allowedExtensions = array(), array $allowedMimeTypes = array(), ImagineInterface $adapter, MetadataBuilderInterface $metadata = null)

    parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail, $allowedExtensions, $allowedMimeTypes, $metadata);

    $this->imagineAdapter = $adapter;

如您所见,参数 8 需要一个接口。现在在我的服务中,我没有传递第 8 个参数:

sonata.media.provider.image:
         class: %application_sonata_media.image_class%
         arguments:
            - [sonata.media.provider.image]
            - [@sonata.media.filesystem.local]
            - [@sonata.media.cdn.server]
            - [@sonata.media.generator.default]
            - [@sonata.media.thumbnail.format]
            - [@sonata.media.buzz.browser]
            - [@sonata.media.metadata.proxy]
         tags:
            -  name: sonata.media.provider 
         calls:
                       - [ setTemplates, [  helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig, helper_view: SonataMediaBundle:Provider:view_youtube.html.twig  ] ]

我尝试以不同的方式传递它,例如(= array given):

     arguments:
        - [sonata.media.provider.image]
        - [@sonata.media.filesystem.local]
        - [@sonata.media.cdn.server]
        - [@sonata.media.generator.default]
        - [@sonata.media.thumbnail.format]
        - [@sonata.media.buzz.browser]
        - [@sonata.media.metadata.proxy]
        - [imagine_interface]

我什至尝试创建一个加载接口的新服务:

test.imagine:
   class: Imagine\Image\ImagineInterface

sonata.media.provider.image:
     class: %application_sonata_media.image_class%
     arguments:
        - [sonata.media.provider.image]
        - [@sonata.media.filesystem.local]
        - [@sonata.media.cdn.server]
        - [@sonata.media.generator.default]
        - [@sonata.media.thumbnail.format]
        - [@sonata.media.buzz.browser]
        - [@sonata.media.metadata.proxy]
        - [@test.imagine]
     tags:
        -  name: sonata.media.provider 
     calls:
                   - [ setTemplates, [  helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig, helper_view: SonataMediaBundle:Provider:view_youtube.html.twig  ] ]

然后我得到了错误:

Cannot instantiate interface Imagine\Image\ImagineInterface

现在我没有想法了。我还能尝试什么?

【问题讨论】:

【参考方案1】:

Sonata 基础提供程序在其构造函数中有 2 个可选参数 - $allowedExtensions$allowedMimeTypes

因为您将数组传递给一个类,所以存在一个隐藏错误,即您只填充了前 7 个参数(其中需要第 8 个参数)。

你添加了额外的参数是正确的,但是它们的类型是错误的。您的最后修改不起作用,因为您无法从界面提供服务 - 提供的错误说明相同)

试试这个(使用适当的图像适配器):

 sonata.media.provider.image:
         class: Server\BaseBundle\Provider\ImageProvider
         arguments:
            - sonata.media.provider.image
            - @sonata.media.filesystem.local
            - @sonata.media.cdn.server
            - @sonata.media.generator.default
            - @sonata.media.thumbnail.format
            - []
            - []
            - @sonata.media.adapter.image.gd
            - @sonata.media.metadata.proxy
         tags:
            -  name: sonata.media.provider 
         calls:
            - [ setTemplates, [  helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig, helper_view: SonataMediaBundle:Provider:view_youtube.html.twig  ] ]

在奏鸣曲中有一些已经实现的适配器:

sonata.media.adapter.image.gd sonata.media.adapter.image.imagick sonata.media.adapter.image.gmagick

您也可以查看this。它描述了您可以覆盖服务的方式。我认为这是更清晰的方法。例如,要覆盖生成器类,我会这样使用它:

myown.media.provider.file:
        class: Application\MediaBundle\Provider\DemoProvider
        parent: sonata.media.provider.file
        tags:
            -  name: sonata.media.provider 
        calls:
            - [setGenerator, ["@my_own_generator"]] 

【讨论】:

看起来干净的方法面临来自奏鸣曲媒体的错误,其中服务调用在 DI 中硬编码。我有一段时间没有进一步挖掘,但我无法让它发挥作用。

以上是关于Symfony2 覆盖 Sonata 媒体图像提供程序。(将接口传递给构造函数)的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 Sonata Media Bundle 自定义图像裁剪

Symfony2,Sonata MediaBundle:向表中添加新字段

Symfony2 Sonata Media Bundle -- 上传图片时出错

Symfony2、Sonata、UserBundle:当用户启用更新时发送电子邮件

Sonata 媒体包中的图像路径

自 Symfony2 更新到 2.8 以来覆盖注册表单(SonataUserBundle)