私は実際に自分の Symfony2 プロジェクトに取り組んでいる学生ですが、問題の解決策が見つからないのは数日後です。
更新: 03.09.2013
現在のバージョンの symfony と sonata 管理バンドルがあり、管理画面に複数の画像をアップロードするフォームが必要です。
私が提示する次のコードは、このインストール ドキュメントに基づいています。
http://sonata-project.org/bundles/admin/master/doc/reference/recipe_file_uploads.html
私の場合、バンドルにエンティティ Projects (Pf\Bundle\BlogBundle\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\BlogBundle\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 とアノテーションを同時に使用するのはよくないと思います...そうですか?
どんな助けでも大歓迎です!