Datei Upload mit einem Yii Active Record

Datei Upload mit einem Yii Active Record

 

Ein Datei Upload über ein Active Form in Yii zu realisieren, ist gar nicht so schwer, wie man zunächst annimmt. In diesem Artikel möchte ich eine kleine Anleitung bieten, wie man so etwas realisieren könnte. Dabei greife ich zunächst nicht auf weitere Bibliotheken etc zurück, sondern realisiere so etwas mit den Bordmittel von Yii.

Grundsätzlich muss ein Formular für einen Datei Upload ein “enctype=’multipart/form-data’” enthalten, da sonst Dateien vom Browser erst gar nicht übermittelt werden. Dies können wir bei einem CActiveForm wie folgt realisieren:

1
2
3
4
5
<?php $form=$this->beginWidget('CActiveForm',array(
    'id'=>'app-gutschein-form',
    'enableAjaxValidation'=>false,
    'htmlOptions' => array('enctype' => 'multipart/form-data'),
));

Desweiteren müssen wir dann noch das entsprechende Feld zu einem Datei-Feld ändern.

1
2
3
4
5
6
<div class="row">
  <?php echo $form->labelEx($model,'banner'); ?>
  <?php echo $form->fileField($model,'banner'); ?>
  <?php echo $form->error($model,'banner'); ?>
  <?php echo CHtml::image(Yii::app()->request->baseUrl.'/images/uploads/'.$model->banner,"Bild",array("width"=>200)); ?>
</div>

Da in jedem ActiveRecord in Yii entsprechende Regeln für die Datenübermittlung notwendig sind, müssen wir auch für unsere Datei-Felder hier noch entsprechende regeln definieren. Im Rules Part fügen wir also noch folgende Array’s hinzu:

1
2
array('banner', 'file','types'=>'jpg, gif, png','allowEmpty'=>false,'on'=>'update'),
array('banner', 'length', 'max'=>255, 'on'=>'insert,update'),

Nun müssen wir uns um den Datei-Upload im Yii Controller kümmern. Wir gehen beispielsweise in die actionUpdate(), falls der Dateiupload an dieser Stelle eingebaut werden soll. Hier fragen wir erst den alten Namen des Banners ab und reichen anschließend per Massenzuweisung alle Daten des Formulars an das ActiveRecord weiter. Nun holen wir uns die Instanz des hochgeladenen Bildes über CUploadedFile. Wenn kein Bild hochgeladen wurde, gibt es auch keinen Dateinamen hierzu, also weisen wir hier an, dass das ActiveRecord den bisherigen Banner-Namen beibehalten sol,l anderenfalls möchten wir den Namen aus der ActiveRecord_id, dem String “_banner” und dem bisherigen Dateinamen abspeichern. Nach dem Speichern des ActiveRecord Objektes fragen wir zunächst noch einmal ab, ob eine Datei hochgeladen wurde und Speichern die Datei anschließend in Images/Uploads des Arbeitsverzeichnisses.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if(isset($_POST['ArObject']))
{
  $filename_banner_old = $model->banner;
  $model->attributes=$_POST['ArObject'];
  $uploaded_banner = CUploadedFile::getInstance($model, 'banner');
  if(empty($uploaded_banner)){
    $model->banner = $filename_banner_old;
  }else{
    $filename_banner = $model->id.'_banner'.$uploaded_banner;
    $model->banner = $filename_banner;
  }
  if($model->save()){
    if(!empty($uploaded_banner)){
      $uploaded_banner->saveAs(Yii::app()->basePath.'/../images/uploads/'.$filename_banner);
    }
    $this->redirect("index.php");
  }
}

Hier wurde noch nicht berücksichtigt, wann eine Datei wieder gelöscht wird. Dies muss unter Umständen natürlich auch noch geschehen.

Wenn es noch einen einfacheren Weg gibt, eine Datei hochzuladen, so lasst es mich wissen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert