SonataMediaBundle - 如何使用自定义文件输入

Posted

技术标签:

【中文标题】SonataMediaBundle - 如何使用自定义文件输入【英文标题】:SonataMediaBundle - How to use custom file input 【发布时间】:2014-03-31 16:13:09 【问题描述】:

我有一个寻宝项目,我在其中使用 AngularJS 来管理它可能包含的不同问题。这些问题属于不同类型。因此,有些可能包含文件输入,有些可能不包含。在这个项目中,我还使用 Symfony 和 SonataMediaBundle 来管理我的文件和图像。

由于我的 html 模型(主要是我的表单)可以根据用户的操作而改变,所以我不能使用 Symfony 的内置工具来生成表单。因此,我所有的表格都是定制的。当我想上传一些文件时,这给我带来了 SonataMediaBundle 的问题。如果用户选择了一个文件,当表单被发送时,这个文件将通过 POST 发送到控制器中的一个方法。因此,我想将收到的这个文件发送到 SonataMediaBundle 以便它可以管理它,但是我在文档中的任何地方都没有找到如何做这样的事情。

理论上,这真的很简单。在我的控制器中,当我收到文件输入时,我想让 SonataMedia 管理上传(即复制到正确位置等...),但我不知道该怎么做。

【问题讨论】:

也许你应该看看:gist.github.com/romaricdrigon/6291435。这允许您结合 AngularJS 使用 Symfony 构建表单的方式。您可以按照自己喜欢的方式构建表单,然后将其从后端返回到您的 SPA。 【参考方案1】:

使用 symfony2 而没有利用它的好处,你犯了一个大错误,你应该正确构建你的应用程序,但就你的问题而言,symfony 没有任何限制,而是你自己如何使用它。你可以得到奏鸣曲来自容器的媒体管理器服务,您必须手动设置媒体管理器所需的所有设置器,并且您必须手动进行文件大小、文件 mimetype 等验证。下面是演示如何将文件存储在奏鸣曲媒体包

/* Before class use these*/
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Application\Sonata\MediaBundle\Entity\Media;

public function uploadAction()


$file = $this->get('request')->files->get('filefieldname');

    if (!$file instanceof UploadedFile || !$file->isValid()) 
        return new Response(json_encode(array(
            'event' => 'uploader:error',
            'data'  => array(
                'message' => 'Missing file.',
            ),
        )));
    

/* validate max min size for the file */
/* validate mime type for the file */
/* Get sonata media manager service from container    */ 
$mediaManager = $this->container->get('sonata.media.manager.media');
/* create new instance of sonata media class in my case entity is located at 
* Application\Sonata\MediaBundle\Entity\Media 
*/
$media = new Media();
$media->setBinaryContent($file);
$media->setContext('default'); 
$ImagemimeTypes = array('image/jpeg', 'image/png');
$FilemimeTypes = array('application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/msword', 'application/pdf', 'application/x-pdf');
if (in_array($file->getMimeType(), $FilemimeTypes)) 
    $media->setProviderName('sonata.media.provider.file');

if (in_array($file->getMimeType(), $ImagemimeTypes)) 
    $media->setProviderName('sonata.media.provider.image');

 /*If you have other providers in your app like vimeo /dailymotion etc
 then do set here i have shown you the demo for adding image/file in sonata media */
/*other setters if you want to set like enabled/disable etc*/
 $mediaManager->save($media);
// end function

但是再一次你必须做很多返工,而 symfony 已经为你提供了方便

【讨论】:

【参考方案2】:

Bundle 正是为了缩小 Symfony 和 SonataMedia 之间的差距。 SonataMedia 是为原始 php 制作的,而 SonataMediaBundle 将 Symfony 接口附加到 SonataMedia;您正在重写 Bundle 的大部分功能。要获得如何正确完成的一个很好的例子,请查看 Bundle 的代码;)

很抱歉,如果您对下一个建议进行了彻底的考虑,基于问题中的有限信息,我无法确定。 Symfony 表单非常灵活,并提供了许多您不应该尝试自己重新实现的关键功能(例如 CSRF-tokens)。大多数问题都可以通过表单系统得到很好的解决方案。如果一个表单是变形的(有许多字段,基于 UI 交互)并且不能被多种表单类型处理,你仍然有选择。如果您可以设置一个 GET 参数来指示当前正在发送哪种类型的表单,那么您可以将其传递给 FormBuilder。您甚至可以选择为整个应用程序构建一个大表单,其中包含您曾经使用过的每个字段 - 这有点浪费,但仍然比尝试将发布+奏鸣曲连接在一起更好。第一个版本最受伤害的是一些额外的字节和空字段。您尝试做的最小伤害是引入严重的安全漏洞。

【讨论】:

我可以做你提到的,如果不是为了这个。我最多可以有 20 个问题,每个问题可以有不同的类型(我有 10 个不同类型的问题)。因此,我必须将 20000 种不同的表单传递到我的页面,以便我可以管理所有不同的可能性,这似乎不是一个好的选择...... 如果您说您有 10 种类型,我将其理解为字段有 10 种变体。如果每个问题都可以有任何类型的表格,那么我看到两个步骤。 1)创建一个FormType类,它构建了这么多字段,它可以包含10种类型中的任何一种(例如,如果type1有一个文本和一个单选,type2有一个文本和3个复选框,那么你构建一个带有文本的表单,一个收音机和 3 个复选框)。 2) 获取一个表单构建器,并为每个问题 $builder->add() 这个 FormType 的一个实例(它的构造函数参数可以处理各个“选择”列表以及哪些字段确实需要添加。 如果您仍然觉得这样不能轻松解决问题,请编辑问题,以便我们看到 10 个问题类型中的至少 2-3 个和 20 个问题中的 2-3 个,最好是某种组合,这样我们就可以弄清楚为什么这会带来比应有的更大的挑战。

以上是关于SonataMediaBundle - 如何使用自定义文件输入的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SonataMediaBundle 在树枝中获取图像路径?

SonataMediaBundle - 如何上传图片?

使用 SonataMediaBundle,我如何找出可用的媒体提供商?

如何将 SonataMediaBundle 画廊限制为单个提供商?

如何从SonataMediaBundle的图库中获取图像网址,以便与FOSRestBundle一起使用?

使用 SonataMediaBundle 上传到 AmazonS3