Ponieważ jakiś czas już grzebię sobie w Yii Framework jednym z nurtujących mnie zagadnień do zrealizowania było stworzenie formularza z możliwością uploadu pliku, zdjęcia. Mój formularz dodaje zdjęcie i plik dla przykładu wykorzystałem tutorialowy blog Yii. W tworzeniu stron internetowych niezwykle ważne są elementu formularza typu file. A więc zacznijmy od kontrolera, który będzie miał za zadanie zapisanie naszego pliku w określonej przez nas lokalizacji. Dla kontrolera musimy utworzyć bądź zmodyfikować dwie akcje actionCreate(), actionUpdate().
Kontroler:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
public function actionCreate() { $model=new Post; if(isset($_POST['Post'])) { $model->attributes=$_POST['Post']; //Pobieramy atrybuty z formularza $model->image=CUploadedFile::getInstance($model,'image'); //Przypisujemy nazwę wysłanego pliku do atrybutu image modelu Post $model->file=CUploadedFile::getInstance($model,'file'); //Przypisujemy nazwę wysłanego pliku do atrybutu file modelu Post if($model->save()) { $images_path = realpath(Yii::app()->basePath . '/../files/images'); //określamy ścieżkę zapisu zdjęcia $files_path = realpath(Yii::app()->basePath . '/../files/files'); //określamy ścieżkę zapisu pliku $model->image->saveAs($images_path . '/' . $model->image); //zapis image $model->file->saveAs($files_path . '/' . $model->file); //zapis pliku // redirect to success page $this->redirect(array('view','id'=>$model->id)); } } $this->render('create',array( 'model'=>$model, )); } |
Funkcja Create jest dość prosta, ponieważ polega ona na pobraniu nazwy zdjęcia i pliku do zapisu w bazie danych, oraz na zapisie nowych plików pobranych poprzez formularz. Większy problem zaczyna się przy akcji Update, co opisałem dokładnie krok po kroku:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
public function actionUpdate() { $model=$this->loadModel(); if(isset($_POST['Post'])) { $old_image = $model->image; // Zapisujemy w zmiennej stary atrybut image $old_file = $model->file; // Zapisujemy w zmiennej stary atrybut pliku $model->attributes=$_POST['Post']; / Pobieramy atrybuty z formularza //Zapisujemy do zmiennej pobrane dane z formularzy(jeśli pola były użyte) $image = CUploadedFile::getInstance($model,'image'); //Zapisujemy do zmiennej pobrane dane $file = CUploadedFile::getInstance($model,'file'); //Sprawdzamy, czy pole image było wypełnione, jeśli nie to zostanie użyta zmienna $old_image if (is_object($image) && get_class($image)==='CUploadedFile') { $model->image = $image; } else { $model->image = $old_image; } //Sprawdzamy, czy pole file było wypełnione, jeśli nie to zostanie użyta zmienna $old_file if (is_object($file) && get_class($file)==='CUploadedFile') { $model->file = $file; } else { $model->file = $old_file; } //Zapis plików if($model->save()){ if (is_object($image) && get_class($image)==='CUploadedFile') { $images_path = realpath(Yii::app()->basePath . '/../files/images/'); $model->image->saveAs($images_path.$model->image); } if (is_object($file) && get_class($file)==='CUploadedFile') { $files_path = realpath(Yii::app()->basePath . '/../files/files/'); $model->file->saveAs($files_path.$model->file); } $this->redirect(array('view','id'=>$model->id)); } } $this->render('update',array( 'model'=>$model, )); } |
Kolejnym elementem naszego formularza który przeanalizuję będzie model w którym ustawimy wszystkie reguły. Na początek definiujemy nasze dwie zmienne image, oraz file.
Model:
|
<?php class Post extends CActiveRecord { public $image; public $file; |
Teraz przechodzimy do funkcji rules(), gdzie ustawimy nasze reguły. Ja z powodu braku takiej potrzeby nie ustawiałem żadnych reguł po za rodzajem pliku.
Model:
|
public function rules() { return array( array('image', 'file', 'types'=>'jpg, gif, png, jpeg', 'allowEmpty'=>true), array('file', 'file', 'types'=>'zip, rar', 'allowEmpty'=>true), |
A więc jedyne, co nam pozostało do wykonania to edycja pliku widoku. Tak jak wspominałem, korzystałem z tutorialowego blogu yii tak więc edytowałem plik _form.php dla widoku Post, lecz można to zrobić z dowolnym formularzem np. wygenerowanym przez Gii. Wystarczy teraz wkleić kod widoku naszych pól image i file formularza.
Widok:
|
<div class="row"> <?php echo $form->labelEx($model, 'image'); ?> <?php echo $form->fileField($model, 'image'); ?> <?php echo $form->error($model, 'image'); ?> </div> <div class="row"> <?php echo $form->labelEx($model, 'file'); ?> <?php echo $form->fileField($model, 'file'); ?> <?php echo $form->error($model, 'file'); ?> </div> |
Najlepiej to wkleić przed ostatnimi elementami formularza lecz ułożenie jest dowolne 🙂
|
<div class="row buttons"> <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?> </div> <?php $this->endWidget(); ?> |
Od teraz możemy się cieszyć uploadem plików i zdjęć z naszego formularza. Na dzień dzisiejszy nie potrzebowałem tworzyć akcji usuwania plików lecz może zabiorę się za to już wkrótce:)
Thanks for laret 🙂