Code

Symfony HowTo: Fileupload mit sfWidgetFormInputFileEditable

symfony

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!

SVN: Revisionen rückgängig machen

Wenn man so rumbastelt wie ich, kann es schon mal vorkommen dass man Sachen eincheckt, die man dann später wieder bereut.

Um nun eine gesamte Revision rückgängig zu machen, ist wie folgt vorzugehen (Mal angenommen, ich will r13 rückgängig machen):

1
2
3
4
$ svn merge -c -13 http://example.com/repo/trunk
# Dadurch wird das Changeset von r13 rückwärts angewendet
$
$ svn commit -m 'Undoing changes commited in r13'

Eh voila!

Gefunden in den Common Use-Cases im SVN-Book