Как бы вы добавили загрузку файла в Symfony2 DataFixture?

Я не могу понять, как бы я добавил загрузку файла в DataFixture. Я пытаюсь загрузить изображение фиктивного содержимого, которое загружают мои приборы. Это похоже на то, что было бы полезно знать.


person ornj    schedule 06.09.2012    source источник
comment
Для Symfony4.1 stackoverflow.com/a/53380949/624533   -  person Sudhakar Krishnan    schedule 19.11.2018


Ответы (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();
    }
}

Надеюсь, это кому-то поможет! Извините, если что-то не так. Я все еще учусь :)

person Fred John    schedule 18.09.2013
comment
Вы включаете слишком много логики в свой класс сущности! Все эти помощники (получить абсолютные, получить фикстуры ..) должны быть реализованы в каком-нибудь вспомогательном сервисе .. или в классе FixtureData - person Almog Baku; 13.10.2013
comment
Это меня просто спасло - самый важный трюк - установить для параметра $ testMode UploadedFile значение true. - person Maerlyn; 30.04.2014

Я нашел ответ на свой вопрос. Мне нужно использовать класс Symfony\Component\HttpFoundation\File\File для создания файла. Symfony будет физически перемещать файл, а не создавать копию, поэтому вам нужно либо иметь новый файл для каждого прибора, либо использовать copy() для создания копии файла, которую можно переместить.

$image = new Image();
$file = new File('path/to/file.jpg');
$image->file = $file;
$om->persist($image);

Что-то такое.

person ornj    schedule 07.09.2012
comment
Изображение - это моя сущность, которая обрабатывает загрузку файлов, symfony.com/doc/current/ поваренная книга / doctrine / file_uploads.html - person ornj; 07.09.2012
comment
Используйте UploadedFile вместо File!, некоторые пакеты (например, VichUploader) проверяют, что файл загружен ... (На самом деле мне потребовался один час, чтобы выяснить, почему VichUploader не загружает файл моего устройства в gaufrette.) - person Almog Baku; 13.10.2013
comment
Это не работает. Рабочее решение находится в ответе @Fred Duarte. - person ioleo; 16.03.2015

Изображение, которое вы хотите использовать, должно находиться в вашей папке «Web», и вам следует использовать только строку указателя файла (например, «/web/images/test.png») в вашем Data Fixture.

Как правило, вам следует избегать хранения изображений в своей базе данных.

person Ken Hannel    schedule 07.09.2012
comment
Конечно. Я пытаюсь загрузить файл через объект и позволить Doctrine управлять файлом. Используя в качестве примера эту статью, я пытаюсь развить это позволяет загружать временные файлы устройством данных. - person ornj; 07.09.2012

я создал класс 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

person Jorge Olaf    schedule 19.02.2014