0

私は実際に自分の Symfony2 プロジェクトに取り組んでいる学生ですが、問題の解決策が見つからないのは数日後です。

更新: 03.09.2013

現在のバージョンの symfony と sonata 管理バンドルがあり、管理画面に複数の画像をアップロードするフォームが必要です。

私が提示する次のコードは、このインストール ドキュメントに基づいています。

http://sonata-project.org/bundles/admin/master/doc/reference/recipe_file_uploads.html

私の場合、バンドルにエンティティ Projects (Pf\Bundle\BlogBu​​ndle\Entity\Projects.php) があります。このエンティティには、$image1 (ドキュメントのファイル名に相当) と、もちろんマップされていないプロパティ ファイルがあります。すべての文字列と必要に応じて構成されています。(私の場合、ファイル名の代わりに image1 を使用することに注意してください // ドキュメント)。

<?php

namespace Pf\Bundle\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * Projects
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Pf\Bundle\BlogBundle\Entity\ProjectRepository")
  * @ORM\HasLifecycleCallbacks()
 */
class Projects
{

    const SERVER_PATH_TO_IMAGE_FOLDER = '/uploads/medias';

    /**
     * Unmapped property to handle file uploads
     */
    private $file;

    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file = null)
    {
        $this->file = $file;
    }

    /**
     * Get file.
     *
     * @return UploadedFile
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * Manages the copying of the file to the relevant place on the server
     */
    public function upload()
    {
        // the file property can be empty if the field is not required
        if (null === $this->getFile()) {
            return;
        }
        // we use the original file name here but you should
        // sanitize it at least to avoid any security issues

        // move takes the target directory and target filename as params
        $this->getFile()->move(
            Projects::SERVER_PATH_TO_IMAGE_FOLDER,
            $this->getFile()->getClientOriginalName()
        );

        // set the path property to the filename where you've saved the file
        $this->image1 = $this->getFile()->getClientOriginalName();

        // clean up the file property as you won't need it anymore
        $this->setFile(null);
    }

    /**
     * Lifecycle callback to upload the file to the server
     */
    public function lifecycleFileUpload() {
        $this->upload();
    }

    /**
     * Updates the hash value to force the preUpdate and postUpdate events to fire
     */
    public function refreshUpdated() {
        $this->setUpdated(date('Y-m-d H:i:s'));
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="image1", type="string", length=100)
     */
    private $image1;

    //...

    /**
     * @var datetime
     *
     * @ORM\Column(name="updated", nullable=true)
     */
    private $updated;

     /**
     * Set updated
     *
     * @param string $updated
     * @return Projects
     */
    public function setUpdated($updated)
    {
        $this->updated = $updated;

        return $this;
    }

    /**
     * Get updated
     *
     * @return string 
     */
    public function getUpdated()
    {
        return $this->updated;
    }
}

また、管理コントローラー (Pf\Bundle\BlogBu​​ndle\Admin\ProjectsAdmin.php) もあり、次のフォームがあります (「sonata 管理方法」で作成):

<?php
namespace Pf\Bundle\BlogBundle\Admin;

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;

class ProjectsAdmin extends Admin
{
    // setup the default sort column and order
    protected $datagridValues = array(
        '_sort_order' => 'DESC',
        '_sort_by' => 'id'
    );

    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('file', 'file', array('required' => false, 'data_class' => null))
            ->add('image2',  'text')
            ->add('image3', 'text')
            ->add('link', 'text')
            ->add('download_link', 'text')
            ->add('content1', 'text')
            ->add('content2', 'text')
            ->add('title', 'text')
            ->add('thumbnail', 'text')
        ;
    }

    public function prePersist($projects) {
        $this->manageFileUpload($projects);
    }

    public function preUpdate($projects) {
        $this->manageFileUpload($projects);
    }

    private function manageFileUpload($projects) {
        if ($projects->getFile()) {
            $projects->refreshUpdated();
        }
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('title')
        ;
    }

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('title')
        ;
    }
}

私にはいくつかの問題があります:

  • 新しいプロジェクトを作成しようとすると、アップロードしようとするたびに image1 が null のように見えます。エンティティでnull可能にできますが、データベースでURLをまったく取得できません

    'INSERT INTO Projects... の実行中に例外が発生しました... 整合性制約違反: 1048 列 'image1' を null にすることはできません

  • 管理者で既存のプロジェクトを編集することで、うまくいくようです..ファイルをアップロードするときにエラーは発生しませんが、データベースに一時パスを取得し、適切なフォルダーにファイルが移動されていません.

アップロード機能が呼び出されていないようです。デバッグしようとしましたが、解決策が見つかりません。

ドキュメントを順を追って説明しました。唯一の違いは、エンティティの構成に .yaml ファイルを使用しないことです。必要ですか? symfony でアノテーションを使用していますが、orm.yaml とアノテーションを同時に使用するのはよくないと思います...そうですか?

どんな助けでも大歓迎です!

4

1 に答える 1

0

「このトピックに関する情報」http://symfony.com/doc/current/cookbook/form/form_collections.htmlを見たことがありますか?

画像フォームを親フォームに埋め込む必要があります。例えば、

->add('myImage','collection',array('type'=>new MyImageType()))

複数の image1、image2、... を配置する代わりに、別のフォーム クラスを作成します。MyImageType() を作成し、それをコレクション タイプとして既存のフォームに追加します。

その方向で頑張ってください、頑張ってください。

于 2013-08-29T06:15:50.827 に答える