Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu zend_framework Kanał ATOM (tag: zend_framework)

Autor wpisu: batman, dodany: 28.03.2012 09:00, tagi: zend_framework

Zend Framework to jeden z najpopularniejszych frameworków PHP, który poznawałem jako jeden z pierwszych. Z wersji na wersję przybywało w nim funkcjonalności, zamieniając go ze zbioru luźno związanych komponentów w pełnoprawny framework MVC (z małym przymrużeniem oka). Od ponad roku programiści z niego korzystający czekają na wersję oznaczoną numerem 2, która ma przywrócić blask nieco zaśniedziałej chwały. Czy to się uda? Ciężko stwierdzić. Obecnie mamy możliwość sprawdzenia jak sobie radzi trzecia beta Zend Frameworka 2. Niestety dokumentacja jest tak samo kiepska jak w przypadku ZF 1 i większość informacji musimy wyszukiwać w sieci lub kodzie.

Co się zmieniło? Wszystko. Jeśli znacie aktualna wersję Zend Frameworka, to i tak będzie musieli uczyć się go na nowo, a aplikacje napisane w oparciu o pierwszą wersję, nie będą działać z wersją drugą. Jest tak dlatego, ponieważ ZF 2 został podzielony na moduły, które w pierwszej wersji były traktowane po macoszemu. Od drugiej wersji każdy moduł, to niezależny byt, który można bez żadnego problemu wyjąć z jednej aplikacji i wstawić do innej. Co więcej, moduły można pakować do archiwum phar, przez co ich utrzymanie i użycie będzie jeszcze prostsze. Moduły stały się pojemnikami na wszystko co chcemy zamknąć w obrębie jednej przestrzeni nazw. I tak, moduł może zawierać specyficzne biblioteki, zasoby (css, javascript, pliki graficzne), całą aplikację MVC, konfigurację – wszystko jest niezależne od innych modułów. Pozwoli to na budowanie klocków, z których będzie można tworzyć modułowe aplikacje.

Spore zmiany zaszły również w obsłudze requestu od momentu jego przesłania do aplikacji, do wygenerowania odpowiedzi. Pamiętacie jak to wyglądało w ZF 1? Pluginy, action helpery, metody w kontrolerze, boostrap i cała magia z tym związania. W ZF 2 już tego nie ma. Teraz mamy eventy, przy pomocy których możemy podpiąć się pod większość etapów obsługi żądania. Od strony programisty za wiele się nie zmieni. I tak trzeba napisać kod, który robi coś w określonym momencie, ale od strony “bebechów”, twórcy ZF 2 odwalili kawał dobrej roboty.

Podobnie wygląda sprawa wstrzykiwania zależności. Z wierzchu nie widać za bardzo co się zmieniło, ponieważ nadal musimy bawić się wielowymiarowymi, zagnieżdżonymi tablicami przekazywanymi do jakiegoś obiektu. Jednak jeśli zajrzymy pod maskę, znajdziemy coraz popularniejsze w PHP DI (dependency Injection). Podobnie jak w przypadku eventów, DI również zostało dobrze przemyślane.

Kolejną sporą zmianę zauważymy w widoku. Teraz akcja kontrolera zwraca obiekt typu ViewModel, który odpowiedzialny jest za ustawienie szablonu, pliku widoku i przekazanie zmiennych. Ciekawie wygląda opcja zagnieżdżania, pozwalająca osadzić jeden ViewModel wewnątrz innego, co w rezultacie pozwoli na wpływanie na zawartość dowolnego elementu szablonu.

Przejrzałem Zend Frameworka 2 dosyć pobieżnie, przebrnąłem przez Quick Start i stworzyłem kilka modułów w ramach treningu, jednak już teraz mogę powiedzieć, że szykuje się nam porządnie wykonany framework. Nie przeprowadzałem żadnych testów wydajnościowych, w końcu cały czas mamy do czynienia z betą, obawiam się jednak, że ZF 2 może być wolniejszy od swojego poprzednika. Jest to mocno subiektywne odczucie i nie powinniście się nim sugerować podczas wybierania frameworka. Ogromnym plusem ZF 2 jest podzielenie wszystkiego na niezależne moduły, co na pewno przyczyni się do powstania ogromnej bazy paczek podobnych do gem-ów powszechnie wykorzystywanych w Railsach. Przynajmniej taką mam nadzieję. Ile poczekamy na stabilną wersję ZF 2? Nie wiem. Zgaduję, że chłopaki czekali na PHP 5.4 i w jednej z kolejnych wersji beta zobaczymy rozbudowany komponent Zend_Tool, pozwalający na uruchomienie aplikacji opartej na ZF 2 bez konieczności posiadania jakiegokolwiek serwera. Nieważne jaka by nie była przyczyna opóźnień, czekam na finalną wersję z niecierpliwością.

Autor wpisu: Marek, dodany: 17.03.2012 08:58, tagi: zend_framework

Ostatnio miałem przyjemność zapoznać się z niedocenianym wcześniej przeze mnie tematem używania kodów kreskowych w aplikacji. Czytnik bez żadnych problemów działał  na Ubuntu 10.04, na którym go testowałem. Kody kreskowe służyły tu do szybszego wyszukiwania uczestników konferencji. Pod względem implementacyjnym dzięki Zend_Barcode wygenerowanie takiego kodu nie stanowi żadnego problemu.

Najprostszy przykład:

$barcodeOptions = array('text' => 'Hekima Blog');
Zend_Barcode::render('code128', 'image', $barcodeOptions);

Tworzy obrazek z kodem kreskowym, w którym zaszyty jest napis „Hekima Blog”. Do renderowania kodu użyłem obiektu klasy Zend_Barcode_Object_Code128, który obsługuje wszystkie znaki ASCII.

Wynik:

Bardziej przydatna wydaje się jednak możliwość dołączenia takiego obrazka do pdfa (np. z zaproszeniem dla danego uczestnika konferencji). Tu mamy dwie możliwości:

  • zapisanie wcześniej wygenerowanego obrazka do katalogu tymczasowego i ręczne dołączenie go do pliku pdf (przydatne jeśli korzystamy np. z TCPDF)
  • dołączenie kodu kreskowego do pliku PDF w locie:
// tworzymy pdfa i jego pierwszą stronę
$pdf = new Zend_Pdf();
$pdf->pages[0] =  new Zend_Pdf_Page('A4');

// i ustawiamy jako źródło obiektu renderującego kod do pdf
$renderer = new Zend_Barcode_Renderer_Pdf();
$renderer->setResource($pdf);

// ustawiamy tekst i font do generowania kodu
    $barcodeOptions = array(
       'text' => 'Hekima Blog',
       'font' => APPLICATION_PATH . '/../data/fonts/Radley-Italic.ttf'
);

// renderujemy kod kreskowy
Zend_Barcode::render('code128', $renderer, $barcodeOptions);

W opcjach kodu kreskowego musimy podać font, który posłuży do wpisania kodu do pdfa. Czcionkę ściągnąłem z Google Web Fonts i umieściłem ją w katalogu data/fonts/.

Poniżej krótki przykład użycia:

/**
 * Klasa służy do generowania kodów kreskowych
 * @author Marek Pietrzak
 */
class BarcodeController extends Zend_Controller_Action {

    /**
     * Generowanie kodu kreskowego do obrazka
     */
    public function indexAction() {
        // wyłączenie generowania layoutu i widoku
        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        // ustawiamy tekst
        $barcodeOptions = array('text' => 'Hekima Blog');

        // renderujemy kod do obrazka
        Zend_Barcode::render('code128', 'image', $barcodeOptions);
    }

    /**
     * Generowanie kodu kreskowego do pliku PDF
     */
    public function pdfAction() {
        // wyłączamy generowanie layoutu i widoku
        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        // tworzymy pdfa i jego pierwszą stronę
        $pdf = new Zend_Pdf();
        $pdf->pages[0] =  new Zend_Pdf_Page('A4');

        // i ustawiamy jako źródło obiektu renderującego kod do pdf
        $renderer = new Zend_Barcode_Renderer_Pdf();
        $renderer->setResource($pdf);

        // ustawiamy tekst i font do generowania kodu
        $barcodeOptions = array(
           'text' => 'Hekima Blog',
           'font' => APPLICATION_PATH . '/../data/fonts/Radley-Italic.ttf'
        );

        // renderujemy kod kreskowy
        Zend_Barcode::render('code128', $renderer, $barcodeOptions);
    }

}

Jeśli kogoś bardziej interesuje to zagadnienie to polecam dokumentację

Autor wpisu: zleek, dodany: 08.03.2012 09:24, tagi: zend_framework, php

Podczas przygotowywania formularzy z wykorzystaniem Zend_Form zachodzi czasami konieczność przekazania do formularza zmiennej lub zmiennych, które będą warunkowały odpowiednie wygenerowanie formularza. Przykładem może tutaj być przedstawienie innego formularza dla kobiety i innego dla mężczyzny. Powstaje wówczas konieczność “poinformowania” formularza o płci użytkownika. Stworzenie jakiejś dodatkowej metody i wywołanie jej na instancji formularza nie przyniesie zamierzonego [...]

Autor wpisu: Marek, dodany: 06.03.2012 21: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...

Autor wpisu: Marek, dodany: 06.03.2012 21:55, 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: d3ut3r, dodany: 04.03.2012 10:32, tagi: zend_framework, php

Coś dawno nie pisałem, tak dawno że zapomniałem o tym blogu :D ale do rzeczy ponieważ teraz mam trochę czasu wolnego postanowiłem zrobić coś konstruktywnego z dziedziny PHP wybór padł na poznanie jakiegoś frameworka. Kilka godzin przeszukiwania google i zostały 2 do wyboru SYMFONY i ZF. Miałem przyjemność modyfikować w małym zakresie strony oparte zarówno o ZF jak i o SYMFONY więc mam malutkie pojęcie o każdym z nich. Wybór ostatecznie padł na ZF, wraz z nauką ZF chciałbym na łamach tego blogu poprowadzić serię tutoriali na temat ZF a pierwszym z nich będzie utworzenie najprostszego projektu.

1. Przygotowania

Do wykonania poniższych czynności będziemy potrzebować:

  • Środowiska testowego (polecam zainstalowanie pakietu xampp)
  • Paczki z zend framework którą możemy pobrać tutaj(ja pobrałem paczkę Zend Framework 1.11.11 Full)
  • 10 minut wolnego czasu :)

2. Do dzieła

Pierwsze co musimy zrobić to wypakować gdzieś nasz framework sam zdecydowałem się na katalog D:\xampp\ZF. Po wypakowaniu powinniśmy mieć strukturę jak na screenie poniżej.

Następnym krokiem będzie zmiana zmiennej systemowej PATH. Sposób edycji tej zmiennej może być różny na różnych systemach operacyjnych ja opiszę tutaj sposób dla Windows XP:

  1. Klikamy “Mój komputer” prawym przyciskiem myszy
  2. Z menu kontekstowego wybieramy “Właściwości”
  3. Przechodzimy na zakładkę “Zaawansowane”
  4. Klikamy przycisk “Zmienne środowiskowe”
  5. Na liście odnajdujemy zmienną PATH i klikamy dwukrotnie
  6. W nowo otwartym okienku na samym końcu dopisujemy: ;d:\xampp\ZF\bin
  7. Jeżeli do tej pory tego nie zrobiliśmy warto dopisać również ;d:\xampp\php\bin oraz ;d:\xampp\mysql\bin 

Powyższe czynności pozwolą wykonać nam komendy zf, php, mysql z dowolnego miejsca na dysku.

Kolejnym naszym zadaniem będzie zmodyfikowanie pliku php.ini dla mojego pakietu xampp ścieżka do pliku jest następująca: d:\xampp\php\php.ini otwieramy plik za pomocą dowolnego edytora a następnie odnajdujemy linię:

include_path = ".;D:\xampp\php\PEAR"

i zmieniamy ją na:

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

Autor wpisu: batman, dodany: 02.03.2012 11:40, tagi: zend_framework

Ludzie z Twittera odwalili kawał dobrej roboty dostarczając Bootstrap, bibliotekę pozwalającą niewielkim nakładem pracy przygotować dobrze wyglądającą stronę. Wystarczy odpowiednio przygotować kod HTML, aby gotowe reguły CSS ozdobiły stronę i sprawiły, że przestanie wyglądać siermiężnie. Do tego dochodzi bogaty zbiór pluginów JavaScript z powodzeniem uzupełniający niezastąpione jQuery UI.

Jakiś czas temu zabrałem się za tworzenie uniwersalnej aplikacji opartej o Zend Framework, mającej na celu ułatwienie tworzenie prostych szablonowych stron. Pierwszym usprawnieniem jakie do tej aplikacji dodałem, są formularze ostylowane przy pomocy wspomnianego Bootstrapa. Jedyne co należy zrobić, to dołączyć do projektu odpowiednie pliki CSS i JavaScript oraz dziedziczyć w klasie formularza po klasie Batman_Form_Horizontal lub Batman_Form_Inline. Pierwsza z nich odpowiada za standardowy formularz, druga za typowy formularz logowania. W tworzonej klasie formularza nie można zapomnieć o wywołaniu z klasy rodzica metody init.

class Application_Form_Book extends Batman_Form_Horizontal
{
    public function init()
    {
        $title = new Zend_Form_Element_Text('title');
        $title->setLabel('Tytuł')
              ->setRequired(true)
              ->addValidator(new Zend_Validate_NotEmpty());

        $submit = new Zend_Form_Element_Submit('btn_save');
        $submit->setLabel('Zapisz')
               ->setIgnore(true);

        $this->addElement($title);
        $this->addElement($submit);

        parent::init();
    }
}

Kod przykładowej aplikacji znajdziecie na GitHubie, a samą aplikację możecie zobaczyć pod adresem http://batman.my.phpcloud.com/universalzf/user/add.

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