Doctrineでファイルのアップロードを処理する方法を調査しました__DIR__.'/../../../../web/'.$this->getUploadDir();
が、将来的にweb/
ディレクトリを変更する可能性があるため、パスをハードコーディングしたくありません。それをより柔軟にする方法は?私はこれを見つけましたが、エンティティ内からより柔軟に行う方法についての質問には答えていません
4 に答える
ここでは、エンティティクラスをフォームモデルとして使用しないでください。それは単にその仕事には適していません。エンティティにpath
プロパティがある場合、格納できる有効な値はnull
、(ファイルがない場合)およびファイルへのパスを表す文字列のみです。
別のクラスを作成します。これがフォームのモデルになります。
class MyFormModel { /** @Assert\File */ private $file; /** @Assert\Valid */ private $entity; // constructor, getters, setters, other methods }
フォームハンドラー(DICを介して構成された個別のオブジェクト;推奨)またはコントローラー:
... if ($form->isValid()) { /** @var \Symfony\Component\HttpFoundation\File\UploadedFile */ $file = $form->getData()->getFile(); /** @var \Your\Entity\Class */ $entity = $form->getData()->getEntity(); // move the file // $path = '/path/to/the/moved/file'; $entity->setPath($path); $someEntityManager->persist($entity); return ...; } ...
フォームハンドラー/コントローラー内で、DICから任意の依存関係/プロパティ(アップロードディレクトリへのパスを含む)にアクセスできます。
リンクしたチュートリアルは機能しますが、これは悪いデザインの例です。エンティティはファイルのアップロードを認識してはなりません。
コントローラの外部からルートディレクトリにアクセスするには、サービス構成の引数として「%kernel.root_dir%」を挿入するだけです。
service_name:
class: Namespace\Bundle\etc
arguments: ['%kernel.root_dir%']
次に、クラスコンストラクターでWebルートを取得できます。
public function __construct($rootDir)
{
$this->webRoot = realpath($rootDir . '/../web');
}
parameters.ymlで変数を使用できます。このように、必要に応じてパスを変更できます。
例えば :
# app/config/parameters.yml
# Upload directories
upload_avatar_dir: /uploads/avatars
upload_content_dir: /uploads/content
upload_product_offer_dir: /uploads/product-offer
...
Symfonyのドキュメントで説明されているように、エンティティがファイルのアップロードを処理している場合にエンティティが拡張できる抽象クラスを作成することで、これを処理しました。ファイル配列を作成したので、setメソッドで既存のファイルパスのコピーを作成できるため、更新が成功したときにファイルシステムから削除したり、エンティティに追加のプロパティを定義せずに削除したりできます。
use Symfony\Component\HttpFoundation\File\File;
abstract class FileUploadEntity
{
private $files;
public function __set($name, File $value)
{
$this->files[$name] = $value;
}
public function __get($name)
{
if (!is_array($this->files)) $this->files = array();
if (!array_key_exists($name, $this->files)) {
return null;
}
return $this->files[$name];
}
public function getUploadRootDirectory()
{
return $this->getWebDirectory() . $this->getUploadDirectory();
}
public function getWebDirectory()
{
return __DIR__ . "/../../../../web/";
}
public function getUploadDirectory()
{
$year = date("Y");
$month= date("m");
return "images/uploads/$year/$month/";
}
public function getEncodedFilename($name)
{
return sha1($name . uniqid(mt_rand(), true));
}
// this should be a PrePersist method
abstract public function processImages();
// This should be defined as a Doctrine PreUpdate Method
abstract public function checkImages();
// this should be a PostPersist method
abstract public function upload();
// this should be a PostUpdate method and delete old files
abstract public function checkUpload();
// This should be a PostRemove method and delete files
abstract public function deleteFile();
}