upload behaviour
Written by: adziki
May 30, 2008
Upload behaviour jest pomocny przy wysyłaniu plików formularzem html. Kod razem z przykładem użycia można ściągnąć z naszego repozytorium svn.
Podstawowe możliwości
Jest to prosty mechanizm pozwalający na automatyczne zapisywanie plików wysłanych formularzem. Zakładamy, że mamy model Myfile, który łączy się z tabelą myfiles. W tabeli interesuje nas jedno pole myfile typu string (255). W widoku tworzymy prosty formularz który umożliwi wysłanie do interesującego nas pola plik, zamiast tekstu:
$form->create(Myfile,array('type'=>'file'));
$form->input(Myfile.myfile, array('type'=>file));
$form->end('Submit');
Do utworzenia pola uploadu plików można również skorzystać z uploadHelper
W kontrolerze nie musimy dodawac nic poza standardowym kodem który umożliwi zapisanie rekordu. Behaviour wykryje, ze dane pole zawiera plik i automatycznie go przetworzy.
W modelu wystarczy dopisać nastepujaca linie, zeby cieszyć się jego podstawowymi funkcjami.
var $actsAs = array('Upload');
Upload behaviour zapisuje pliki w katalogu APP/webroot/files/[nazwa modelu]. Nazwa pliku jest znormalizowaną nazwą pliku wysyłanego (zawiera tylko litery alfabetu łacińskiego i podkreślenia).
Jeśli nie korzystamy z walidacji, behaviour “testuje” każde pole typu string w modelu - czy nie wysłano za jego pomocą plików. Jeśli tak w polu zostaje umieszczona nazwa pliku a plik zostaje zapisany w docelowym katalogu.
Usuwanie plików
Jeśli nie korzystamy z uploadHelper, należy dodać do formularza pole:
$this->form->input('myfile_delete', array('type'=>'checkbox'));
Zaznaczając checkbox można w łatwy sposób usuwać pliki.
Dla zapewnienia spójności plików z powiązanymi rekordami w bazie danych pliki są również usuwane automatycznie:
- przy usuwaniu rekordu,
- oraz przy edycji rekordu połączonej z wysłaniem nowego pliku w miejsce poprzedniego.
Walidacja
Jeśli chcemy skorzystać z walidacji do modelu trzeba dołączyć konfigurację walidacji:
function __construct(){
parent::__construct();
$this->validate = array(
'myfile' => array(
array('rule'=>array('validateUpload'), 'on'=>'create', 'message'=>'', 'last'=>true, 'allowEmpty'=>false),
array('rule'=>array('validateUpload'), 'on'=>'update', 'message'=>'Nie wysłano', 'required'=>false),
array('rule'=>array('validateMime','image'), 'message'=>__("Plik musi być obrazkiem (gif, jpeg albo png)",true)),
),
);
}
Dodatkowo, żeby walidacja przebiegała bez problemów konieczne jest dodanie poniższego kodu do modelu:
function save(&$data){
if(parent::save($data)){
return true;
}
$data = $this->data;
return false;
}
Jak dotąd dostępne są dwie funkcje walidacji:
- validateUpload - za jej pomocą można sprawdzić poprawność uploadu pliku
- validateMime - można określić dozwolone typy plików
validateMime
W validateMime są trzy sposoby zdefiniowania zakresu dozwolonych plików:
- Predefiniowane ustawienie - jak narazie tylko ‘image’
(odpowiada wyrażeniu regularnemu:'/^image\/(pjpeg|jpeg|jpg|png|gif)$/');
użyte w powyższym przykładzie - Tablica typów mime - np
array('text/plain','text/css');
(Nie może to być tablica wyrażeń regularnych) - Dowolne wyrażenie regularne (Perl-Compatible)
upload Helper
Jest to rozszerzenie dla standardowego formHelper, można je pobrać w naszym repozytorium svn. uploadHelper dostarcza jak dotąd tylko jedną funkcję, bardzo prosta w użyciu, utrzymana w stylu form helpera:
echo $upload->input('myfile', array('delete'=>false, 'preview'=>array('rel'=>'lightbox')));
Standardowo funkcja input generuje link do pliku (jeśli już jakiś został przesłany), pole typu file do wysłania pliku formularzem i pole checkbox do usuwania pliku. Funkcja upload::input() umożliwia dostęp do parametrów linku podglądu, oraz pola do usuwania plików poprzez elementy tablicy opcji o kluczach ‘preview’ oraz ‘delete’. W powyższym przykładzie checkbox do usuwania plików został wyłączony, a do odnośnika został dodany atrybut rel=”lightbox”.
Posted in



June 11th, 2008 at 12:12 pm
W jednym z projektów potrzebowałem sprawdzać wielkość uploadowanego pliku.
Oto jak to osiągnąłem.
Do pliku behaviora upload.php dołożyłem nową metodę:
function validateFilesize(&$model, $variable, $params){
$valid = true;
if(!is_array($variable)){
debug('UploadBehavior->validateMime()');
return false;
}
foreach($variable AS $variableName => $variableValue){
if ($variableValue['size'] > $params){
$valid = false;
}
}
if(!$valid){
if(!empty($model->data[$model->name][$model->primaryKey])){
//$tempModel = new $model->name();
$data = $model->find(array($model->name.’.’.$model->primaryKey => $model->data[$model->name][$model->primaryKey]));
$model->data[$model->name][$variableName] = $data[$model->name][$variableName];
} else {
$model->data[$model->name][$variableName] = ”;
}
return false;
}
return true;
}
Teraz w $validate oprócz rodzaju pliku, możemy również sprawdzić jego wielkość.
'zdjecie1' => array(
array('rule'=>array('validateUpload'), 'message'=>'Please, choose proper file to save', 'last'=>true),
array('rule'=>array('validateMime','image'), 'message'=> "File must be an image (gif, jpeg, or png)",true),
array('rule'=>array('validateFilesize','1024000'), 'message'=> "File size exceeded",true),
),
Powyzszy przyklad pozwoli na upload tylko plików tych plików grafiki, których wielkość nie przekracza 1MB.
June 11th, 2008 at 12:23 pm
Czasami potrzebna jest zmiana nazwy pliku i jego rozmiaru czy stopnia kompresji (np przy pomocy komponentu AydImage), a następnie zapis zmienionej nazwy do bazy.
W takim przypadku konieczne jest odpięcie behaviora od pól z nazwami plików. Najprostszy sposób: unset($this->Offer->validate);. Oczywiście stracimy wtedy możliwość walidowania również innych pól modelu, ale w powyższym przypadku jest to dopuszczalne.