Я не могу понять, как бы я добавил загрузку файла в DataFixture. Я пытаюсь загрузить изображение фиктивного содержимого, которое загружают мои приборы. Это похоже на то, что было бы полезно знать.
Как бы вы добавили загрузку файла в Symfony2 DataFixture?
Ответы (4)
Хотя этот вопрос был задан год назад, похоже, что существует не так много информации о том, как загрузить файл с помощью инструментария данных доктрины. Я смог найти только этот пост.
Я искал и использовал немного другой подход, чем у ornj. (Возможно, это связано с обновлениями Symfony.)
Мне сначала пришлось
use Symfony\Component\HttpFoundation\File\UploadedFile;
а затем использовал copy (), чтобы скопировать изображение, потому что, как сказал ornj, он переместит его.
copy($art1->getFixturesPath() . '01.jpg', $art1->getFixturesPath() . '01-copy.jpg');
Затем создайте и добавьте файл, используя:
$file = new UploadedFile($art1->getFixturesPath() . '01-copy.jpg', 'Image1', null, null, null, true);
$art1->setFile($file);
$manager->persist($art1);
Если бы я не установил последний параметр в значение «true» в конструкторе «UploadedFile», поскольку он выдает неизвестную ошибку при запуске «doctrine: fixtures: load». Этот параметр - «Активен ли тестовый режим». Увидев, что это приспособление, имеет смысл перейти в тестовый режим.
Метод getFixturesPath () просто извлекает путь, по которому хранятся мои образцы изображений:
// Entity file
public function getFixturesPath()
{
return $this->getAbsolutePath() . 'web/uploads/art/fixtures/';
}
Метод getAbsolutePath () был взят из Загрузки файлов доктрины.
Полный рабочий код: Entity:
<?php
//src/User/MyBundle/Entity/Art.php
namespace User/MyBundle/Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
*
* Art Entity
*
* @ORM\Entity(repositoryClass="User\MyBundle\Entity\Repository\ArtRepository")
* @ORM\Table(name="art")
* @ORM\HasLifecycleCallbacks
*/
class Art
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=100)
*/
protected $title;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $path;
/**
* @Assert\File(maxSize="6000000")
*/
private $file;
private $temp;
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 up
// when displaying uploaded doc/image in the view.
return 'uploads/art';
}
public function getFixturesPath()
{
return $this->getAbsolutePath() . 'web/uploads/art/fixtures/';
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
// do whatever you want to generate a unique filename
$filename = sha1(uniqid(mt_rand(), true));
$this->path = $filename . '.' . $this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
// the file property can be empty if the field is not required
if (null === $this->getFile()) {
return;
}
// if there is an error 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->getFile()->move($this->getUploadRootDir(), $this->path);
// check if we have an old image
if (isset($this->temp)) {
// delete the old image
unlink($this->getUploadRootDir() . '/' . $this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
}
Крепление:
<?php
// src/User/MyBundle/DataFixtures/ORM/ArtFixtures.php
namespace User\MyBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Fredzz\LotwBundle\Entity\Art;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class ArtFixtures extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{
$art1 = new Art();
$art1->setTitle('MyTitle');
$art1->setDescription('My description');
copy($art1->getFixturesPath() . '01.jpg', $art1->getFixturesPath() . '01-copy.jpg');
$file = new UploadedFile($art1->getFixturesPath() . '01-copy.jpg', 'Image1', null, null, null, true);
$art1->setFile($file);
$art1->setUser($manager->merge($this->getReference('user-1')));
$manager->persist($art1);
$manager->flush();
}
}
Надеюсь, это кому-то поможет! Извините, если что-то не так. Я все еще учусь :)
FixtureData
- person Almog Baku; 13.10.2013
Я нашел ответ на свой вопрос. Мне нужно использовать класс Symfony\Component\HttpFoundation\File\File
для создания файла. Symfony будет физически перемещать файл, а не создавать копию, поэтому вам нужно либо иметь новый файл для каждого прибора, либо использовать copy()
для создания копии файла, которую можно переместить.
$image = new Image();
$file = new File('path/to/file.jpg');
$image->file = $file;
$om->persist($image);
Что-то такое.
UploadedFile
вместо File
!, некоторые пакеты (например, VichUploader) проверяют, что файл загружен ... (На самом деле мне потребовался один час, чтобы выяснить, почему VichUploader не загружает файл моего устройства в gaufrette.)
- person Almog Baku; 13.10.2013
Изображение, которое вы хотите использовать, должно находиться в вашей папке «Web», и вам следует использовать только строку указателя файла (например, «/web/images/test.png») в вашем Data Fixture.
Как правило, вам следует избегать хранения изображений в своей базе данных.
я создал класс FileUpload для PHP 5.3+
Как пользоваться?:
из RFC 3023 (типы мультимедиа XML):
Тип мультимедиа верхнего уровня «текст» имеет некоторые ограничения на объекты MIME, и они описаны в [RFC2045] и [RFC2046]. В частности, семейство UTF-16, UCS-4 и UTF-32 не разрешены (кроме HTTP [RFC2616], который использует механизм, подобный MIME).
Разрешить загрузку только файла yaml:
<?php
$file = new FileUpload\FileUpload();
$file->setInput( "file" );
$FileUpload->setAllowedMimeTypes(array(
"text/x-yaml", //RFC 3023
"application/x-yaml", // Ruby on Rails
"text/plain",//Possible option( only text plain )
"text/yaml",//Possible option
"text/x-yaml",//Possible option
"application/yaml",//Possible option
));
$file->setDestinationDirectory("/var/www/html/myapp/");
$file->save();
if ($file->getStatus()) {
echo "Okay";
}
?>
Пример со всеми типами пантомимы:
<?php
$file = new FileUpload\FileUpload();
$file->setInput( "file" );
$file->save();
if ($file->getStatus()) {
echo "is Upload!";
}
?>
<html>
<head>
<title>FileUpload Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<form method="post" action="" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Upload now!" />
</form>
</body>
</html>
GitHub: https://github.com/olaferlandsen/FileUpload-for-PHP