SonataMediaBundle - 如何上传图像?

问题描述 投票:0回答:2

可能应该标题为:“SonataMediaBundle - 缺少的操作方法在哪里?”。

我用 sonataAdminBundle 和 sonataDoctrineORMAdminBundle (以及其他一些)制作了一些管理后端,大多数事情都按预期工作,但我将文件上传和处理留到以后,因为我想“这可能有多难?”。

长话短说 - 是否有任何关于最简单事情的文档 - 即将图像附加到帖子或条目,如何配置奏鸣曲管理类,如何在编辑表单中显示图像拇指等?

文档的第一页以“您可以访问您的管理仪表板”结尾,好像我可以期待那里的一些相关更改,也许媒体管理器已启动并运行,或者其他什么。但事实并非如此。

下一页简要介绍 heplers,然后另一页介绍相当复杂的 vimeo 提供商案例研究。

我在整个网络上进行了搜索,我能想到的最好的办法是带有ajax弹出窗口的上传字段,以及上传文件的列表。

在我的管理课程中,我有:

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('general') ->add('title') ->add('body') ->add('categories') ->end() ->with('media') ->add('images', 'sonata_type_model')

在我的新闻课上:

/** * @ORM\ManyToMany(targetEntity="Application\Sonata\MediaBundle\Entity\Media") */ public $images;

所有 yaml 配置和路由均已实现。

结果是:

Fatal error: Call to a member function add() on a non-object in [some-entity].php

尝试上传图像时,以及带有“加号”符号的图像ID的可选列表(我猜是sonata_type_model字段)。

我被困住了。我能够在一两个小时内用普通的 sf2 创建媒体“管理器”,但这是另一个项目,将当前的项目重写为这种模式意味着“从头开始”。那么 - 怎样才能使 sonataMediaBundle 和 sonataAdminBundle 按预期工作?


编辑:这就是我所做的:

我的新闻类(或任何其他需要上传图片的类):

<?php namespace Some\SiteBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Validator\Constraints as Assert; /** * Some\SiteBundle\Entity\News * * @ORM\Table(name="news") */ class News { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; //some stuff... /** * @var Document documents * @ORM\ManyToMany(targetEntity="Document", cascade={"persist", "remove", "delete"} ) **/ protected $documents; public function __construct() { $this->documents = new ArrayCollection(); } [...] /** * Add documents * * @param Festus\SiteBundle\Entity\Document $documents */ public function addDocument(\Festus\SiteBundle\Entity\Document $document) { $this->documents[] = $document; } /** * set document * * @param Festus\SiteBundle\Entity\Document $documents */ public function setDocument(\Festus\SiteBundle\Entity\Document $document) { foreach ($this->documents as $doc) { $this->documents->removeElement($doc); } $this->documents[] = $document; } /** * Get documents * * @return Doctrine\Common\Collections\Collection */ public function getDocuments() { return $this->documents; } // setters, getters...

我的文档类(需要更改表的名称,因为我在某些服务器上遇到了保留字的问题):

<?php namespace Some\SiteBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Validator\Constraints as Assert; /** * Some\SiteBundle\Entity\Document * * @ORM\Table(name="docs") * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class Document { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\Column(type="string", length=255) * @Assert\NotBlank */ private $name; /** * @ORM\Column(type="string", length=255, nullable=true) */ private $path; /** * @Assert\File(maxSize="6000000") */ private $theFile; /** * @ORM\Column(type="datetime", name="created_at") * * @var DateTime $createdAt */ protected $createdAt; /** * @ORM\Column(type="integer") */ private $type = 1; public function __construct() { $this->createdAt = new \DateTime(); } public function getAbsolutePath() { return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path; } public function getWebPath() { return null === $this->path ? null : $this->getUploadDir().'/'.$this->path; } protected function getUploadRootDir() { // the absolute directory path where uploaded documents should be saved return __DIR__.'/../../../../web/'.$this->getUploadDir(); } protected function getUploadDir() { // get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view. return 'uploads/documents'; } /** * @ORM\PrePersist() * @ORM\PreUpdate() */ public function preUpload() { if (null !== $this->theFile) { //var_dump($this); // do whatever you want to generate a unique name $this->path = uniqid().'.'.$this->theFile->guessExtension(); } } /** * @ORM\PostPersist() * @ORM\PostUpdate() */ public function upload() { if (null === $this->theFile) { return; } // if there is an error when moving the file, an exception will // be automatically thrown by move(). This will properly prevent // the entity from being persisted to the database on error $this->theFile->move($this->getUploadRootDir(), $this->path); unset($this->theFile); } /** * @ORM\PostRemove() */ public function removeUpload() { if ($file = $this->getAbsolutePath()) { unlink($file); } } public function __toString() { return 'Document'; } /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set file * * @param string $file */ public function setTheFile($file) { $this->theFile = $file; } /** * Get file * * @return string */ public function getTheFile() { return $this->theFile; } /** * Set path * * @param string $path */ public function setPath($path) { $this->path = $path; } /** * Get path * * @return string */ public function getPath() { return $this->path; } /** * Set type * * @param string $type */ public function setType($type) { $this->type = $type; } /** * Get type * * @return string */ public function getType() { return $this->type; } /** * Gets an object representing the date and time the user was created. * * @return DateTime A DateTime object */ public function getCreatedAt() { return $this->createdAt; } /** * Gets an object representing the date and time the user was created. * * @return DateTime A DateTime object */ public function getCreatedAtString() { return date_format($this->createdAt, "Y-m-d"); } /** * Set createdAt * * @param datetime $createdAt */ public function setCreatedAt($createdAt) { $this->createdAt = $createdAt; } }

如你所见,大部分内容是从 symfony2 教程复制的。

现在,对于控制器:

<?php namespace Some\SiteBundle; use Some\SiteBundle\Form\Type\ImageShowType; use Some\SiteBundle\Entity\Document; use Sonata\AdminBundle\Admin\Admin; use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Validator\ErrorElement; use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Show\ShowMapper; use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\Request; class NewsAdmin extends Admin { public function __construct($code, $class, $baseControllerName) { parent::__construct($code, $class, $baseControllerName); $this->setFormTheme(array_merge($this->getFormTheme(), array('FestusSiteBundle:Form:image_form.html.twig') )); } protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('ogólne') ->add('title', NULL, array('label' => 'tytuł:')) ->add('body', NULL, array('label' => 'treść:', 'attr' => array( 'class' => 'tinymce', 'data-theme' => 'simple'))) ->add('categories', NULL, array('label' => 'kategorie:')) ->end() ->with('media') ->add('fileName', 'text', array( "label" => 'tytuł obrazka:', 'property_path' => false, 'required' => false )) ->add('theFile', 'file', array( "label" => 'wybierz plik', 'property_path' => false, 'required' => false )) ->end() ; } protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('title') ->add('body') ; } protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('title') ->add('categories') ->add('_action', 'actions', array( 'actions' => array( 'view' => array(), 'edit' => array(), ) )) ; } protected function configureShowFields(ShowMapper $showMapper) { $showMapper->add('title') ->add('body'); } public function validate(ErrorElement $errorElement, $object) { $errorElement ->with('title') ->assertMinLength(array('limit' => 2)) ->end() ; } public function prePersist($news) { $this->saveFile($news); } public function preUpdate($news) { $this->saveFile($news); } public function saveFile($news) { $request = Request::createFromGlobals(); $requestData = current($request->request->all()); $filesData = current($request->files->all()); $document = new Document(); $theFile = $filesData['theFile']; $name = $requestData['fileName']; if($theFile != NULL){ $document->setName($name); $document->setTheFile($theFile); $news->setDocument($document); } } }

我的基包类扩展了管理包类,我可以覆盖模板:

<?php namespace Some\SiteBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class SomeSiteBundle extends Bundle { public function getParent() { return 'SonataAdminBundle'; } }

SomeSiteBundle/resources/views/CRUD/base_edit.html.twig

中,我稍微更改了模板,让用户看到当前设置的图片:

<div class="sonata-ba-collapsed-fields"> {% for field_name in form_group.fields %} {% if admin.formfielddescriptions[field_name] is defined %} {% if field_name == 'fileName' %} <h5 style="margin-left: 40px">Obecny obrazek:</h5> {% if object.documents[0] is defined %} <img style="margin: 0 0 0 40px; border: 1px dotted #ccc" src="{{ asset(object.documents[0].webPath) }}" /> {% else %} <div style="margin-left: 40px">brak</div> {% endif %} <hr><h5 style="margin-left: 40px">Wczytaj nowy:</h5> {% endif %} {{ form_row(form[field_name])}} {% endif %} {% endfor %} </div>

现在我每条新闻只使用一张图片(“特色图片”),无论如何,这有点过分了,因为我使用的是带有 jbimages 插件的tinyMCE,所以无论如何我都可以将图像放入新闻正文中。为了让 jbimages 插件正常工作,你必须设置一些tinyMCE选项:

------这部分涉及tinymce和tinymce捆绑包以及tinymce插件:---------

$config['img_path'] = '/web/uploads/documents';

(或任何其他适合您的路径)在
web/bundles/stfalcontinymce/vendor/tiny_mce/plugins/jbimages/config.php
。 (当然,您需要先安装 stfalcon tinymce 包)。然后我编辑了一些
web/bundles/stfalcontinymce/js/init.jquery.js
以允许阅读
config.yml
中的更多选项:

themeOptions.script_url = options.jquery_script_url; //mine: themeOptions.convert_urls = options.convert_urls; themeOptions.relative_urls = options.relative_urls; themeOptions.remove_script_host = options.remove_script_host; themeOptions.document_base_url = options.document_base_url;

最后在

config.yml

[...] stfalcon_tinymce: include_jquery: true tinymce_jquery: true textarea_class: "tinymce" relative_urls : false convert_urls : false remove_script_host : false document_base_url : "http://somesite.home.pl/web/" theme: [...]

仅此而已,AFAIR。希望这有帮助;-)

php symfony sonata-admin symfony-sonata
2个回答
3
投票
也许您可以在以下内容中找到您问题的答案: /admin/sonata/media/media/create?provider=sonata.media.provider.image&context=default

我对您的其他解决方案感兴趣,请发布代码。谢谢


0
投票
考虑在单独的服务器上实施文件存储的最佳实践。它会发送什么文件或文件的链接,您可以使用 Symfony byundle

https://packagist.org/packages/avtonom/media-storage-client-bundle

if($file instanceof UploadedFile){ $this->get('avtonom.media_storage_client.manager')->sendFile($file, $clientName, $context); }
    
© www.soinside.com 2019 - 2024. All rights reserved.