4

file画像をアップロードするフィールドがあるフォームがあります。この画像を A​​mazon S3 にアップロードする必要があります。これを段階的に構築して、ローカルディスクに画像をアップロードし始めましたが、現在は機能しています。

エンティティPageを保存する前に、アップロードの成功をテストすることをお勧めします。私はこのコードの塊で終わった

    /**
     * @ORM\Column(name="objectThumbnail", type="string", length=255, nullable=true)
     */
    protected $objectThumbnail;

    /**
     * This is not a column in the database but it's mapping a field from the form
     *
     * @Assert\File(maxSize="600000000")
     */
    public $file;

    ...

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {
        if (null !== $this->file) {
            // generate a unique filename
            $this->objectThumbnail = $this->getGuid().'.'.$this->file->guessExtension();
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->file) {
            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->file->move($this->getUploadRootDir(), $this->objectThumbnail);

        unset($this->file);
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if ($file = $this->getAbsolutePath()) {
            unlink($file);
        }
    }

それは完璧です、それは魅力のように機能しています。file属性の公開範囲のために Symfony (2.1.7) が叫んでいるだけで、大したことはありません。

次に、S3 レイヤーを統合する必要があります。Gaufretteそのために、 andを使用すると思いますStreamWrapper

今、私はそれを行うための最良の方法を見つけるのに苦労しています. Filesystemエンティティでサービスにアクセスするにはどうすればよいですか? このようにするのは本当にきれいですか?エンティティで S3 上の画像のアップロードを処理するのは、私には少しぎこちなく感じます。

どのようにそれを行うことをお勧めしますか?

乾杯、

マキシム

4

2 に答える 2

5

エンティティでサービスを使用することは良い方法ではありません。この例では、検証、永続化、およびアップロードを実行するフォーム ハンドラーを作成することをお勧めします。

私はあなたのニーズに合った例を書きました

//...
//inside a creation controller action
//...
//create a new page entity
$page = new Page();

//get your page form class
$form = $this->createForm(new PageForm(), $page);

//call your form handler
$formHandler = new PageFormHandler(
        $form,
        $this->get('request'),
        $this->get('your.gaufrette.filesystem'),
        $this->get('your.page.manager')
);

//form is valid ?
if ($formHandler->process()) {         
    //flash message, redirection etc
}

ハンドラー クラス

namespace YourCompagnyBundle\Form\Handler;

use YourCompagnyBundle\Entity\Page;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Gaufrette\Filesystem;


class PageFormHandler
{
    protected $form;
    protected $request;
    protected $pageManager;
    protected $filesystem;

    public function __construct(Form $form, Request $request, Filesystem $filesystem, $pageManager)
    {
        $this->form    = $form;
        $this->request = $request;
        $this->filesystem = $filesystem;
        $this->pageManager = $pageManager;
    }

    public function process()
    {
        if( $this->request->getMethod() == 'POST' )
        {
            $this->form->bind($this->request);

            if( $this->form->isValid() )
            {
               $this->onSuccess($this->form->getData());               

                return true;
            }
        }

        return false;
    }

    function onSuccess(Page $page)
    {
        //has uploaded file ?
        if($page->getFile() instanceof UploadedFile){
            //do some logic with gaufrette filesystem
           //if page is already managed in database (update), delete previous file


        }
        //storage
        $this->pageManager->save($page);
    }

}

これが役に立ったことを願っています

于 2013-02-15T22:55:11.393 に答える
4

おそらく、基本的に File オブジェクトをエンティティに注入するVichUploaderBundleを確認する必要があり、Gaufrette との統合は非常に簡単です。

于 2013-02-17T17:32:06.627 に答える