W poprzednim wpisie przedstawiłem podstawy przesyłania pliku na serwer przy pomocy Zend Framework. Czas zagłębić się bardziej w to zagadnienie.
Kolejnym przypadkiem, którym się zajmę jest rozbudowa formularza o pole tekstowe przechowujące opcjonalną nową nazwę dla wysyłanego pliku.
Skoro możemy zmienić nazwę pliku, użyty poprzednio walidator Zend_Validate_File_NotExists() już nie spełni swojej roli, bo możemy przesłać plik o takiej samej nazwie jak w katalogu docelowym, o ile podamy w formularzu nową nazwę (którą de facto musimy również zweryfikować).
A więc użyjemy własnego walidatora, który będzie dziedziczył po wcześniej wspomnianym, wprowadzając dodatkowe sprawdzanie dla nowej nazwy pliku. Walidator umieszczam w katalogu /library/My/Validate/File/
require_once 'Zend/Validate/File/NotExists.php';
class My_Validate_File_NotExists extends Zend_Validate_File_NotExists {
/**
* @var string nowa nazwa dla pliku
*/
protected $_newName = null;
public function __construct($directory = array(), $newName = null) {
$this->_newName = $newName;
parent::__construct($directory);
}
public function isValid($value, $file = null) {
// ustawienie nowej nazwy pliku, jeśli podana
if (!empty($this->_newName)) {
$fileName = isset($file['name']) ? $file['name'] : $value;
$file['name'] = $this->_newName . '.' . pathinfo($fileName, PATHINFO_EXTENSION);
}
parent::isValid($value, $file);
}
}
Co tu się dzieje? Dzięki dziedziczeniu i w myśl zasady DRY nasz walidator jest bardzo prosty. W konstruktorze przekazujemy do niego nową nazwę pliku i wywołujemy konstruktor klasy rodzica. Metoda isValid() to serce naszej klasy. Sprawdzamy w niej czy została ustawiona nowa nazwa dla pliku. Jeśli tak, modyfikujemy nazwę przetrzymywaną w tablicy $file, dodając do niej rozszerzenie przesłanego pliku (które wyciągamy przy pomocy funkcji pathinfo()). Tak zmodyfikowane dane poddajemy walidacji klasy Zend_Validate_File_NotExists.
Przejdźmy do klasy formularza:
class Application_Form_Rename extends Zend_Form {
public function init() {
$this->setMethod('post');
$newName = new Zend_Form_Element_Text('newname');
$newName->setLabel('Zmień nazwę pliku:')
->addFilters(array('StringTrim', 'StripTags'));
$file = new Zend_Form_Element_File('filename');
$file->addPrefixPath('My_Validate', '/My/Validate', 'validate')
->setLabel('Plik:')
->setRequired()
->setDestination(APPLICATION_PATH . '/../public/uploads')
->addValidator('Size', true, 1048576)
->addValidator('Extension', false, 'pdf');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Wyślij')
->setIgnore(true);
$this->addElements(array($newName, $file, $submit));
}
public function addRenameValidator($newName) {
$destination = $this->filename->getDestination();
if (!empty($newName)) {
$this->filename->addFilter('Rename', array(
'target' => $destination . DIRECTORY_SEPARATOR . $newName . '.'
. pathinfo($this->filename->getFileName(), PATHINFO_EXTENSION),
'overwrite' => false));
}
$this->filename->addValidator(new My_Validate_File_NotExists($destination, $newName));
}
}
W metodzie init(), inicjującej pola formularza, dodajemy obiekt Zend_Form_Element_Text, który będzie odpowiadał za kontrolkę nowej nazwy pliku. Dalej na obiekcie $file wywołujemy metodę addPrefixPath(), która pomoże później znaleźć klasę naszego walidatora.
Kolejna metoda addRenameValidator() dodaje filtr Zend_Filter_File_Rename(), który zmieni nazwę przesyłanego pliku na nową (o ile ją podaliśmy). Dalej dodajemy do obiektu $filename walidator My_Validate_File_NotExists(), przekazując mu nową nazwę dla pliku.
Przyjrzyjmy się teraz kontrolerowi:
public function renameAction() {
$form = new Application_Form_Rename();
$form->setAction($this->view->url());
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost();
$form->addRenameValidator($data['newname']);
if ($form->isValid($data)) {
if (!$form->filename->receive()) { //odbieramy plik
throw new Zend_Exception('Wystąpił błąd przy odbieraniu pliku!');
}
$db = new Application_Model_DbTable_File();
$db->insertRenamed($form->getValues());
$this->view->msg = 'Plik został pomyślnie zapisany';
} else {
$this->view->msg = 'Wystąpił błąd!';
}
}
$this->view->form = $form;
}
Akcja rename naszego kontrolera bardzo przypomina akcję index z poprzedniego wpisu. Z tym, że:
- przed sprawdzeniem poprawności danych przesłanych z formularza, wywołujemy metodę addRenameValidator(), podając jej nową nazwę pliku (co prowadzi do dodania wyżej opisanego walidatora)
- jeśli wystąpił błąd podczas odbierania pliku, wyrzucamy wyjątek
- jeśli plik został prawidłowo przesłany na serwer, zapisujemy dane do bazy
Został jeszcze model:
Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Zwiń
Czytaj na blogu autora...