Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: zleek, dodany: 02.03.2012 08:58, tagi: php

W dniu wczorajszym zostało wydane PHP w wersji 5.4. Nowa wersja zawiera sporą część bugfixów oraz kilka nowości, a wśród nich między innymi: traits skrócony zapis tablic wbudowany webserwer i wiele innych. Szczegółowy opis zmian wprowadzonych w PHP 5.4 można znaleźć w changelogu. Na pewno przydatne mogą być informacje zawarte w instrukcji migracji z PHP [...]

Autor wpisu: Marek, dodany: 01.03.2012 19:58, tagi: zend_framework

zf

Wygenerowany formularz z mojego poprzedniego wpisu wygląda tak:

<form enctype="multipart/form-data" method="post" action="/zf/test/public/index/rename">
<dl class="zend_form">
  <dt id="newname-label"><label for="newname" class="optional">Zmień nazwę pliku:</label></dt>
  <dd id="newname-element"><input type="text" name="newname" id="newname" value=""></dd>
  <dt id="filename-label"><label for="filename" class="required">Plik:</label></dt>
  <dd>
    <input type="hidden" name="MAX_FILE_SIZE" value="8388608" id="MAX_FILE_SIZE">
    <input type="file" name="filename" id="filename">
  </dd>
  <dt id="submit-label">&#160;</dt>
  <dd id="submit-element">
    <input type="submit" name="submit" id="submit" value="Wyślij"></dd>
</dl>
</form>

Zend Framework podczas generowania formularzy stosuje domyślnie tagi dl, dd, dt. Ja jednak wolę przechowywać elementy formularza w tabeli. Poniżej przedstawiam kod, który chciałbym uzyskać:

<form enctype="multipart/form-data" method="post" action="/zf/test/public/index/rename">
<table>
  <tr>
    <th colspan="2">Wyślij plik</th>
  </tr>
  <tr>
    <td id="newname-label"><label for="newname">Zmień nazwę pliku:</label></td>
    <td><input type="text" name="newname" id="newname" value=""></td>
  </tr>
  <tr>
    <td id="filename-label"><label for="filename">Plik:</label></td>
    <td>
      <input type="hidden" name="MAX_FILE_SIZE" value="8388608" id="MAX_FILE_SIZE" />
      <input type="file" name="filename" id="filename" />
    </td>
  </tr>
  <tr>
    <td colspan="2"><input type="submit" name="submit" id="submit" value="Wyślij"></td>
  </tr>
</table>
</form>

Jak zatem wygenerować formularz w Zend Framework, tak aby jego elementy były zawarte w tabeli? Do tego oczywiście służą dekoratory.

Zmodyfikuję jeszcze tylko formularz dodając do niego opis:

$this->setDescription('Wyślij plik');

Po dodaniu elementów do formularza:

$this->addElements(array($newName, $file, $submit));

Ustawmy mu dekoratory:

// dekoratory formularza
$this->setDecorators(array(
    array('Description', array('tag' => 'th', 'colspan' => 2)),
    array(array('tr' => 'HtmlTag'), array('tag' => 'tr')),
    'FormElements',
    array('HtmlTag', array('tag' => 'table')),
    'Form'
));

Nasz opis będzie znajdował się wewnątrz znaczników th. Po opisie zostaną wygenerowane elementy formularza, które razem z opisem zostaną zawarte w znaczniku table, a ten zostanie otoczony znacznikiem form.

Tutaj jedna uwaga. Dekoratory dodawane są do zmiennej tablicowej _decorators klasy formularza. A więc skoro raz używamy HtmlTag, będzie on użyty jako klucz w tablicy __decorators. Jeśli ponownie chcemy użyć tego samego dekoratora, musimy podać unikalny klucz (tutaj: array(‘tr’ => ‘HtmlTag’) )

Dalej ustawmy dekoratory kontrolek:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Marek, dodany: 01.03.2012 19:56, tagi: zend_framework

Aby wyłączyć renderowanie layoutu w kontrolerze wpisujemy:

$this->_helper->layout->disableLayout();

Metodę disableLayout znajdziemy w klasie Zend_Layout.

Aby wyłączyć renderowanie danego widoku w kontrolerze wpisujemy:

$this->_helper->viewRenderer->setNoRender();

Wywołujemy tutaj przy użyciu helpera metodę setNoRender() klasy Zend_Controller_Action_Helper_ViewRenderer

Autor wpisu: Marek, dodany: 01.03.2012 19:56, tagi: zend_framework

Poniżej przedstawiam maksymalnie uproszczony sposób przesyłania plików na serwer przy pomocy Zend Framework. Zakładam zapis pliku na serwerze, oraz zapis informacji o jego nazwie w bazie danych. Jest to pierwszy z serii artykułów – mam nadzieję, że w prosty sposób wprowadzi w to rozbudowane zagadnienie. A więc do dzieła.

Tworzymy bazę danych. Tutaj użyję SZBD SQLITE3. Bazę umieszczę w katalogu:

data/db/

i nazwę ją:

testfile.db

A więc z katalogu głównego aplikacji wykonujemy:

mkdir -p data/db

A potem:

sqlite3 testfile.db

W konsoli sqlite tworzymy tabelę files:

create table files (
id integer primary key autoincrement,
filename varchar(150));

Gdzie w kolumnie „filename” będziemy przechowywać nazwę pliku. Teraz poinformujemy naszą aplikację o wybranym adapterze bazy danych i jej lokalizacji.

W pliku:

application/configs/application.ini

wpisujemy:

resources.db.adapter = "pdo_sqlite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/testfile.db"

W pliku:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Marek, dodany: 01.03.2012 19:56, tagi: zend_framework

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...

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.