I can't seem to wrap my head around how I would go about adding a file upload to a DataFixture. I'm trying to upload an image for the dummy content my fixtures load. This seems like something that would be useful to know.
Symfony Form component provides FileType class to handle file input element. It enables easy uploading of images, documents, etc. Let us learn how to create a simple application using FileType feature. Step 1 − Create a new application, fileuploadsample using the following command.
Fixtures are used to load a "fake" set of data into a database that can then be used for testing or to help give you some interesting data while you're developing your application. This bundle is compatible with any database supported by Doctrine ORM (MySQL, PostgreSQL, SQLite, etc.).
Although this question has been asked 1 year ago it appears that there is not a lot of information out there on how to upload a file via doctrine data fixture. I could only find this post.
I've been looking and I've taken a slightly different approach than ornj's. (Might have to do with Symfony's updates.)
I first had to
use Symfony\Component\HttpFoundation\File\UploadedFile;
and then used copy() to copy the image because as ornj said it will move it.
copy($art1->getFixturesPath() . '01.jpg', $art1->getFixturesPath() . '01-copy.jpg');
Then create and add the file by using:
$file = new UploadedFile($art1->getFixturesPath() . '01-copy.jpg', 'Image1', null, null, null, true);
$art1->setFile($file);
$manager->persist($art1);
If I did not set the last parameter to ''true'' in the ''UploadedFile'' constructor as it throws an unknown error when running ''doctrine:fixtures:load''. This parameter is "Whether the test mode is active". Seeing it's a fixture it makes sense to set to test mode.
The method ''getFixturesPath()'' just retrieves the path where my sample images are stored:
// Entity file
public function getFixturesPath()
{
return $this->getAbsolutePath() . 'web/uploads/art/fixtures/';
}
The ''getAbsolutePath()'' method has been taken from Doctrine File Uploads.
The full working code: 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);
}
}
}
Fixture:
<?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();
}
}
Hope this helps someone! Sorry if something is wrong. I'm still learning :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With