2012-07-17 128 views
16

大概应该标题为:“SonataMediaBundle--失踪的howto怎么办?”。SonataMediaBundle - 如何上传图片?

我做了一些管理后端与sonataAdminBundle和sonataDoctrineORMAdminBundle(和其他),大部分的事情按预期工作,但我留下文件上传和处理为以后,因为我认为“可能有多困难? ”。

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

documentation的第一页以“您可以访问您的管理员控制台”结束,就好像我可以期待那里发生一些相关更改,也许媒体管理器已启动或正在运行一样。但这种情况并非如此。

下一个页面简要介绍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 CONFIGS和工艺路线的贯彻落实。

结果是: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。希望这有助于;-)

+3

好吧,我已经决定完全抛弃mediabundle现在和实施普通SF2 /学说文件上传方案。如果有人感兴趣,我可以为我的课程发布相关的源代码。 – heliogabal 2012-07-18 11:30:03

+0

我有兴趣,请张贴代码。谢谢。 – Zeljko 2012-07-19 07:14:00

回答

3

也许你能找到答案,你的问题中: /admin/sonata/media/media/create?provider=sonata.media.provider.image &背景=默认

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