Acabo de instalar VichUploader 1.0.0.-beta 7 para Symfony 2.8.2 y para evitar escribir un script de eliminación manual, quiero usar la casilla de verificación de eliminación para el tipo de formulario Vich.
Sin embargo, cuando selecciono la casilla de verificación Eliminar y presiono Actualizar (estoy actualizando la entidad Note con una relación OneToMany con Attachment), la entidad Attachment no se elimina por completo. El archivo se elimina, la propiedad fileName está vacía (no NULL), pero los campos id y updatedAt siguen ahí.
Debido a que la entidad Attachment no se elimina, los enlaces siguen ahí (a archivos que no existen).
¿Es así como se supone que funciona o he configurado mal algo?
Este es mi FormType para la nota:
$builder
->add('body', null, array(
'label' => 'notes.body',
))
->add('attachments', CollectionType::class, array(
'label' => 'notes.attachment',
'entry_type' => NoteAttachmentType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
y mi NoteAttachmentType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('file', VichFileType::class, array(
'required' => false,
'allow_delete' => true, // not mandatory, default is true
'download_link' => true, // not mandatory, default is true
));
}
Tienes el mismo problema aquí, ¿lo resolviste?
VichUploaderBundle no elimina las entidades, debe eliminarlas usted mismo. O probablemente tenga un problema menor de relación en algún lugar que no _persista_ la eliminación de la relación.
Pero entonces no entiendo la utilidad de este código:
// Handler/UploadHandler.php
public function remove($obj, $fieldName)
{
$mapping = $this->getMapping($obj, $fieldName);
$oldFilename = $mapping->getFileName($obj);
// nothing to remove, avoid dispatching useless events
if (empty($oldFilename)) {
return;
}
$this->dispatch(Events::PRE_REMOVE, new Event($obj, $mapping));
$this->storage->remove($obj, $mapping);
$mapping->setFileName($obj, null);
$this->dispatch(Events::POST_REMOVE, new Event($obj, $mapping));
}
Ambas opciones allow_delete
y download_link
en los tipos VichFileType
solo tratan con archivos, no entidades. Las entidades deben eliminarse normalmente con, por ejemplo, $notes->removeAttachement($attachement)
.
La opción allow_delete
en CollectionType
por otro lado, trata de eliminar elementos de la colección.
Solo tenga en cuenta que este paquete es un paquete de carga de archivos, nada más, no lo hace y no debe tratar con sus entidades.
En pocas palabras, puede tener una entidad con un atributo de archivo que no es obligatorio, como un correo electrónico con archivo adjunto. Puede eliminar el archivo adjunto con vichuploader pero conservar el correo electrónico, si desea eliminar el correo electrónico, debe usar doctrine, por ejemplo.
Sé que esta pregunta tiene algunos meses de antigüedad, pero para aquellos que desean que se elimine su entidad de archivo cuando se elimina el archivo (como yo), pueden registrar un detector de eventos simple para que se encargue de eso.
En su services.yml
:
app_bundle.listener.removed_file_listener:
class: AppBundle\EventListener\RemovedFileListener
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: vich_uploader.post_remove, method: onPostRemove }
Y el oyente:
namespace AppBundle\EventListener;
use Vich\UploaderBundle\Event\Event;
class RemovedFileListener
{
/**
*
* <strong i="11">@param</strong> \Doctrine\ORM\EntityManager $em
*/
public function __construct(\Doctrine\ORM\EntityManager $em)
{
$this->em = $em;
}
// make sure a file entity object is removed after the file is deleted
public function onPostRemove(Event $event)
{
// get the file object
$removedFile = $event->getObject();
// remove the file object from the database
$this->em->remove($removedFile);
$this->em->flush();
}
}
Considero esto resuelto con la última sugerencia.
Comentario más útil
Sé que esta pregunta tiene algunos meses de antigüedad, pero para aquellos que desean que se elimine su entidad de archivo cuando se elimina el archivo (como yo), pueden registrar un detector de eventos simple para que se encargue de eso.
En su
services.yml
:Y el oyente: