Was: Zeugs. Thema: Alles mögliche.
Symfony HowTo: Fileupload mit sfWidgetFormInputFileEditable

Für Formulare mit Dateiupload bietet Symfony ja das praktische Widget sfWidgetFormInputFileEditable an. Besagtes Widget (und der dazugehörige Validator sfValidatorFile) überprüft die Datei, speichert sie am angegebenen Ort mit einem einmaligen Dateinamen, und hinterlegt diesen in der Datenbank.
Zuerst also das Widget anlegen:
1 2 3 4 5 6 7 8 | // lib/form/doctrine/DeinForm.class.php $this->widgetSchema['img_normal'] = new sfWidgetFormInputFileEditable(array( 'label' => 'Mitgliederportrait', 'file_src' => '/uploads/mitglieder/'.$this->getObject()->getImgNormal(), 'is_image' => true, 'edit_mode' => !$this->isNew(), 'template' => '%file% %input% %delete% %delete_label%' )); |
file_src und template werden für die Anzeige im Formular benötigt. Der in file_src definierte Pfad wird dann zur Anzeige im Browser verwendet.
Der Rest sollte eigentlich selbsterklärend sein.
Als Nächstes ist der Validator dran:
1 2 3 4 5 | $this->validatorSchema['img_normal'] = new sfValidatorFile(array( 'required' => false, 'path' => sfConfig::get('sf_upload_dir').'/mitglieder', 'mime_categories' => 'web_images' )); |
Und für die Option, die bestehende Datei zu löschen:
1 | $this->validatorSchema['img_normal_delete'] = new sfValidatorPass(); |
Soweit, sogut.
Nun haben wir aber noch ein Problem. Wir können zwar Dateien hochladen, die werden von Symfony auch schön brav am richtigen Ort abgelegt, und in der DB sind immer die richtigen Dateinamen. ABER: Mit der Zeit werdet ihr feststellen, dass sich im angegebenen Uploadordner (hier: /uploads/mitglieder/) jede menge Dateileichen ansammeln. Symfony löscht zwar den Dateinamen aus der DB, versäumt es aber, veraltete Dateien zu löschen (das trifft auch zu wenn die Datei nur ersetzt wird).
Dazu müssen wir die funktion doSave() unserer Formularklasse anpassen:
1 2 3 4 5 6 7 8 9 10 11 | // lib/form/doctrine/DeinForm.class.php public function doSave($con = null) { if ($this->getValue('img_normal') || $this->getValue('img_normal_delete')) { $p = sfConfig::get('sf_upload_dir').'/mitglieder/'.$this->getObject()->getImgNormal(); if (file_exists($p)) unlink($p); } return parent::doSave($con); } |
Eh Voila!
| Print article | This entry was posted by Manuel on 12.10.2009 at 09:22, and is filed under Code. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |

about 5 months ago
Möchte hier anmerken, dass das nur für Doctrine Projekte geht.
Die doSave kann man jedoch auch einwandfrei für das mit propel compativle file upload sfWidgetFormInputFile verwenden.