Saltar al contenido

Symfony2: carga manual de archivos con VichUploaderBundle

Solución:

La respuesta aceptada no es correcta (¿ya?). De acuerdo con la documentación de uso, puede cargar manualmente un File sin usar el componente de formulario de Symfony:

/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 * of 'UploadedFile' is injected into this setter to trigger the  update. If this
 * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
 * must be able to accept an instance of 'File' as the bundle will inject one here
 * during Doctrine hydration.
 *
 * @param File|SymfonyComponentHttpFoundationFileUploadedFile $image
 */
public function setImageFile(File $image = null)
{
    $this->imageFile = $image;

    if ($image) {
        // It is required that at least one field changes if you are using doctrine
        // otherwise the event listeners won't be called and the file is lost
        $this->updatedAt = new DateTime('now');
    }
}

Deberías usar SymfonyComponentHttpFoundationFileUploadedFile en lugar de File:

$file = new UploadedFile($filename, $filename, null, filesize($filename), false, true);

VichUploaderBundle manejará este objeto.

Para combinar las respuestas y abordar un problema con VichUploader y inject_on_load: true cambiando el updatedAt durante el postLoad evento.

Explicación del problema

Dado que la propiedad mapeada de VichUploader no es monitoreada por Doctrine ORM, deberá asegurarse de que al menos una de las propiedades que administra el ORM se cambie para activar la prePersist o preUpdate eventos que VichUploader usa para administrar la referencia del archivo.
Esto generalmente se hace usando un updatedAt Columna DATETIME en su configurador de archivos, pero puede ser cualquier propiedad administrada por el ORM.

postLoad organizador de eventos File problema de instancia

Verificando una instancia de UploadedFile se suministra al método de establecimiento de propiedades mapeado, se asegurará de que updatedAt está cambiado solamente durante los envíos de formularios o cuando se suministran manualmente, en lugar de durante el postLoad evento – donde VichUpload proporciona una instancia de File al mismo método de establecedor mapeado. Lo que de otra manera causaría updatedAt valor en sus vistas para cambiar y potencialmente cambiar el valor de la base de datos si llama $em::flush() cuando instancias de la Image Los objetos son cargados por Doctrine y, por lo tanto, administrados.

Aplicación Entidad Imagen

namespace AppEntity;

use DoctrineORMMapping as ORM;
use SymfonyComponentHttpFoundationFileFile;
use SymfonyComponentHttpFoundationFileUploadedFile;
use VichUploaderBundleMappingAnnotation as Vich;

/**
 * @ORMEntity
 * @VichUploadable
 */
class Image
{

    /**
     * @var DateTime
     * @ORMColumn(name="updated_at", type="datetime")
     */
    private $updatedAt;

    /**
     * @var SymfonyComponentHttpFoundationFileFile
     * @VichUploadableField(mapping="your_mapping", fileNameProperty="image")
     */
    private $imageFile;

    /**
     * @var string|null
     * @ORMColumn(name="image", type="string", length=255, nullable=true)
     */
    private $image;

    public function __construct()
    {
        $this->updatedAt = new DateTime('now');
    }

    //...

    public function setImageFile(File $image = null)
    {
        $this->imageFile = $image;
        if ($image instanceof UploadedFile) {
            $this->updatedAt = new DateTime('now');
        }
    }

}


Luego, puede definir manualmente el archivo para usar en su entidad creando una instancia UploadedFile objeto y configuración de la error argumento como null y el test argumento para true, que inhabilita la validación UPLOAD_ERR_OK y is_uploaded_file() [sic].

Symfony <= 4.0

use SymfonyComponentHttpFoundationFileUploadedFile;

$file = new UploadedFile($path, $filename, null, filesize($path), null, true);

Symfony 4.1 o superior

En Symfony 4.1 y posteriores, el argumento del tamaño del archivo quedó obsoleto.

use SymfonyComponentHttpFoundationFileUploadedFile;

$file = new UploadedFile($path, $filename, null, null, true);

Ahora puede conservar y / o vaciar con éxito su entidad con el archivo cargado manualmente.

$image = new Image();
$image->setImageFile($file);

$em->persist($image);
$em->flush();
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *