Symfony2: Datei-Upload über Doktrin entließ den Vorbereitungs-/Prä-U-Update-Lebenszyklus-Event nicht

StackOverflow https://stackoverflow.com/questions/7307823

  •  26-10-2019
  •  | 
  •  

Frage

Ich habe versucht, das Datei -Upload über Doktrin/Lebenszyklus -Rückrufe zu implementieren, wie hier beschrieben:

http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html#use-lifecycle-callbacks

Bisher funktioniert es, aber das Ereignis für das Präparierer/Präupdat wird nicht abgefeuert, die Funktion "Vorlade" wird nicht aufgerufen. Funktionen wie "Upload" und "removeUpload", die von anderen Lebenszyklusereignissen ausgelöst werden, werden korrekt bezeichnet.

Hat jemand eine Idee, warum das Ereignis nicht abgefeuert wird oder eine Lösung für dieses Problem?

Vielen Dank

War es hilfreich?

Andere Tipps

Ich habe eine andere Lösung für dieses Problem:

Mein Entität hat ein Feld "Updatatedat", das ein Zeitstempel des letzten Updates ist. Da dieses Feld ohnehin festgelegt wird (durch die Zeitstempelerweiterung von GEDMO), verwende ich dieses Feld nur, um die Doktrin dazu zu bringen, zu glauben, dass das Anspruch aktualisiert wurde. Bevor ich das Entität bestehen habe, habe ich dieses Feld manuell eingestellt

if( $editForm['file']->getData() )
    $entity->setUpdateAt(new \DateTime());

Auf diese Weise wird die Entität fortgesetzt (weil es sich geändert hat) und die Funktionen für Vorupdate und Postupdate werden ordnungsgemäß bezeichnet. Natürlich funktioniert dies nur, wenn Ihr Unternehmen über ein Feld verfügt, das Sie so ausnutzen können.

Es gibt eine viel einfachere Lösung im Vergleich zu ändernden Tracking -Richtlinien und anderen Lösungen:

in Controller:

if ($form->isValid()) {
    ...
    if ($form->get('file')->getData() != NULL) {//user have uploaded a new file
        $file = $form->get('file')->getData();//get 'UploadedFile' object
        $news->setPath($file->getClientOriginalName());//change field that holds file's path in db to a temporary value,i.e original file name uploaded by user
    }
    ...
}

Auf diese Weise haben Sie ein persistiertes Feld geändert (hier ist es ein Pfadfeld), also werden Sie in der Funktion in der Funktion () in der Funktion () in der Funktion () in der Funktion (dh Zeitstempel) in der Funktion () in der Funktion (dh Zeitstempel) ausgelöst. Der korrekte Ende wird auf DB bestehen.

Ein Trick könnte sein, die Entität zu ändern, egal was passiert. postLoad.


1 Erstelle ein updatedAt aufstellen.

/**
 * Date/Time of the update
 *
 * @var \Datetime
 * @ORM\Column(name="updated_at", type="datetime")
 */
private $updatedAt;

2 Ein ... kreieren postLoad() Funktion, die Ihre Entität sowieso ändert:

/**
 * @ORM\PostLoad()
 */
public function postLoad()
{
    $this->updatedAt = new \DateTime();
}

3 Aktualisieren Sie dieses Feld einfach korrekt auf Prepersist:

/**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{
    $this->updatedAt = new \DateTime();
    //...update your picture
}

Dies ist im Grunde eine geringfügige Variation von @philipphoffmanns Antwort: Was ich tue, ist, dass ich ein Attribut modifiziere, bevor ich bestehen muss, um das Vor -Uupdate -Ereignis auszulösen, dann habe ich diese Modifikation im Hörer nach.

$entity->setToken($entity->getToken()."_tmp");
$em->flush();

In meinem Zuhörer:

public function preUpdate(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();

    if ($entity instanceof MyEntity) {
      $entity->setToken(str_replace('_tmp', '', $entity->getToken()));
      //...
    }
}

Eine andere Option besteht darin, das Datenbankfeld anzuzeigen, in dem der Dateiname als verstecktes Eingabefeld gespeichert wird und wenn die Datei -Upload -Eingabe ändert, setzt dies auf leeres, sodass die Aktualisierungsereignisse der Doktrin ausgelöst werden. In dem Formbuilder könnten Sie also so etwas haben:

->add('path', 'text', array('required' => false,'label' => 'Photo file name', 'attr' => array('class' => 'invisible')))
 ->add('file', 'file', array('label' => 'Photo', 'attr' => array('class' => 'uploader','data-target' => 'iddp_rorschachbundle_institutiontype_path')))

Path ist eine Eigenschaft, die von der Doktrin verwaltet wird (gleich dem Feldnamen in der DB -Tabelle), und die Datei ist die virtuelle Eigenschaft, um Uploads zu verarbeiten (nicht von der Doktrin verwaltet). Die CSS -Klasse setzt das Display einfach auf keine. Und dann ein einfaches JS, um den Wert des versteckten Eingangsfeldes zu ändern

$('.uploader').change(function(){
        var t = $(this).attr('data-target');
        //clear input value
        $("#"+t).val('');
 });

Für mich hat es gut funktioniert, wenn ich diese Methoden im Controller nur manuell bezeichnete.

Haben Sie Ihre Option "Metadata -Cache -Treiber" in Ihrer config.yml -Datei überprüft?
Wenn es existiert, versuchen Sie einfach, diese Zeile zu kommentieren:

metadata_cache_driver: whateverTheStorage

So was:

#metadata_cache_driver: whateverTheStorage
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top