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

Autor wpisu: batman, dodany: 20.06.2010 13:00, tagi: zend_framework

Każda aplikacja biznesowa posiada opcję zapisz jako CSV. Najczęściej w takim przypadku tworzony jest osobny skrypt, który pobiera dane z bazy i udostępnia je w odpowiednim formacie. Twórcy Zend Frameworka wyszli na przeciw potrzebom programistów i udostępnili helper akcji o nazwie ContextSwitch, który w skrócie można opisać jako mechanizm do zwracania danych w zadanym formacie.

Domyślnie ContextSwitch ofertuje dwa formaty. Są to JSON oraz XML. Jeśli chcemy, aby nasza aplikacja zwracała dane w innym formacie, musimy stworzyć własny kontekst. Sprowadza się to do określenia nazwy kontekstu oraz określenia dodatkowych parametrów, takich jak suffix pliku widoku, nagłówki jakie zostaną użyte w przypadku zastosowania kontekstu oraz funkcje zwrotne, które zostaną wywołane w metodzie init lub postDispatch podczas obsługi danego kontekstu. Żadna z wspomnianych wyżej opcji nie jest wymagana, jednak aby użycie kontekstu miało sens, należy ustawić co najmniej suffix. W przypadku funkcjonalności polegającej na pobieraniu danych, należy dodać jeszcze odpowiednie nagłówki:

$contextSwitch = $this->_helper->getHelper('ContextSwitch');

$contextSwitch->addContext('csv', array(
	'suffix' => 'csv',
	'headers' => array(
		'Content-Type' => 'text/csv',
		'Content-Disposition' => 'attachment; filename=nazwa-pliku.csv'
	)
));
        
$contextSwitch->addActionContext('index', 'csv')
	      ->initContext();

Drugim i zarazem ostatnim krokiem jest stworzenie odpowiedniego pliku widoku ze wskazanym wcześniej suffixem.

Obok CSV można stworzyć kontekst RSS/ATOM, vCard, PDF i wiele innych.

Przykładową aplikację korzystającą z ContextSwitch znajdziecie w repozytorium SVN.

Autor wpisu: batman, dodany: 16.06.2010 18:00, tagi: zend_framework

Zend Frameworku oferuje kilka różnych routerów. Jednym z ciekawszych i zarazem najtrudniejszych w zastosowaniu jest Zend_Controller_Router_Route_Hostname. Router ten w połączeniu z modułami daje ogromne możliwości. Można na przykład stworzyć kilka modułów aplikacji, na które wskazują odpowiadające im subdomeny.

Router można zdefiniować na dwa sposoby – w pliku konfiguracyjnym lub w pliku Bootstrap. W tym przypadku preferuję drugą metodę, co nie oznacza, że pierwsza jest zła. W przypadku korzystania z pliku Bootstrap należy pamiętać o jednej rzeczy. Metoda musi nazywać się _initRouter. W przeciwnym wypadku nasz router nie będzie działał. Niestety nie udało mi się ustalić dlaczego tak się dzieje.

Zend_Controller_Router_Route_Hostname można stosować jako osobny router, jednak wówczas nasza aplikacja nie będzie w stanie dotrzeć do innych akcji niż domyślne. Dzieje się tak dlatego, ponieważ każda ścieżka będzie pasowała do naszego routera. Aby temu zapobiec, należy użyć innego routera – Zend_Controller_Router_Route_Chain. Na szczęście jego wykorzystanie jest banalne i sprowadza się do wywołania metody chain na obiekcie routera hostname.

W praktyce wygląda to następująco:

protected function _initRouter()
{
	$this->bootstrap('frontController');
	$front = $this->getResource('frontController');
	$router = $front->getRouter();

	$hostRouter = new Zend_Controller_Router_Route_Hostname(
		':module.przykladowa-domena.pl',
		array(
			'module' => ''
		)
	);

	$defaultRouter = new Zend_Controller_Router_Route(
		':controller/:action/*',
		array(
			'controller' => 'index',
			'action' => 'index'
		)
	);
	
	$router->addRoute('subdomain', $hostRouter->chain($defaultRouter));
}

Do poprawnego działania, router potrzebuje dwóch parametrów. Pierwszym jest adres, który zostanie przetłumaczony na moduł, drugim domyślna nazwa modułu jaki zostanie użyty w helperze widoku url. Jeśli jako moduł zdefiniujemy pusty string, wówczas helper url zwróci nam adres wskazujący na domenę, bez żadnej subdomeny.

echo $this->url(array(), 'subdomain');
// wyświetli http://przykladowa-domena.pl

Jeśli jako moduł domyślny ustawiony zostanie jakiś string, np admin, wówczas helper wyświetli http://admin.przykladowa-domena.pl. Do helpera możemy przekazać nazwę modułu. Wówczas wygenerowany zostanie adres z odpowiednią subdomeną.

echo $this->url(array('module' => 'jakis-modul'), 'subdomain');
// wyświetli http://jakis-modul.przykladowa-domena.pl

Drugim zdefiniowanym routerem jest Zend_Controller_Router_Route. Dzięki niemu wszystkie parametry przekazane w ścieżce zostaną przetłumaczone na nazwę kontrolera, nazwę akcji oraz dodatkowe parametry.

Autor wpisu: batman, dodany: 16.06.2010 12:46, tagi: zend_framework

Dwa dni temu wydana została nowa wersja Netbeans, oznaczona numerem 6.9. W sumie nie byłoby nic w tym ciekawego, gdyby nie fakt, że do IDE dodana została obsługa Zend Frameworka.

Zanim będziemy mogli skorzystać z możliwości tworzenia projektu ZF, musimy skonfigurować nasze środowisko. Konfiguracja wygląda bardzo podobnie jak w przypadku dodawania ścieżek do zmiennych środowiskowych. Musimy wskazać katalog, w którym znajduje się Zend Framework oraz katalog z plikiem wykonywalnym php.

Po poprawnym skonfigurowaniu IDE, można stworzyć projekt PHP w oparciu o Zend Framework. Projekt będzie posiadał standardową strukturę katalogów. Niestety dodawanie elementów frameworka do projektu (np formularze, akcje, czy moduły) sprowadza się do wpisywania tych samych komend, z których byśmy korzystali w wierszu poleceń. Jedyną różnicą jest to, że Netbeans podpowiada nam składnię poleceń.

Prezentację możliwości nowej wersji Netbeans możecie obejrzeć na oficjalnej stronie tego środowiska.

Autor wpisu: sokzzuka, dodany: 15.06.2010 00:02, tagi: zend_framework, php

Kaskadowość większości ludzi związanymi z web developementem pewnie kojarzy się z kaskadowymi arkuszami styli (CSS). Jest to poniekąd słuszne skojarzenie, ponieważ daje pewne wyobrażenie czym ona jest.

W CSS-ach kaskadowość znaczy nie mniej, nie więcej tyle, że właściwości stylu zdefiniowane dla elementów wyżej w drzewie dokumentu propagują się w dół drzewa aż do momentu kiedy nie zostaną nadpisane przez właściwości elementów niżej w hierarchii.

W PHP istnieje technika oparta na podobnych założeniach, realizowana dzięki magicznej funkcji __autoload. Na czym więc polega ? Załóżmy, że mamy pewną hierarchię klas: --A

---B ----E

---C ----D ----E Każda z tych klas dziedziczy bezpośrednio lub pośrednio z klasy A. Załóżmy teraz, że chcielibyśmy zmienić zachowanie wszystkich klas dziedziczących z A. Jednym z rozwiązań jest po prostu modyfikacja odpowiedniej metody z klasy A, jest to oczywiście najlepsze wyjście, z kilkoma wyjątkami, z których najpoważniejszym jest to, że klasa A należy do pewnej zewnętrznej biblioteki.

Klasycznym przykładem tego typu są formularze dziedziczące z Zend_Form. Mamy już gotowych n-bardzo dużo formularzy, jednak nagle okazało się, że trzeba im globalnie coś zmienić. Nie możemy za bardzo modyfikować samego Zend_Form-a ponieważ należy on do zewnętrznej biblioteki i w razie modyfikacji go, będzie problem z migracją do nowszych wersji frameworka.

Zmiana tych n-bardzo wielu klas, aby dziedziczyły z innej pośredniej klasy, która dziedziczy z Zend_Form będzie procesem bardzo pracochłonnym.

W tym momencie z pomocą przychodzi nam kaskadowość. Dzięki niej będziemy mogli podmienić oryginalną klasę Zend_Form, bez modyfikacji jej kodu.

Po pierwsze będzie nam potrzebna odpowiednia struktura katalogów: -test_cascading --base ---application ----forms ---library ----Zend --modified ---library ----Zend

Naszą zmodyfikowaną klasę Zend_Form umieścimy w podkatalogu “modified” w takiej samej ścieżce jak w katalogu “base”.

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

Autor wpisu: batman, dodany: 13.06.2010 14:00, tagi: zend_framework

Razem z Zend Framework otrzymujemy kilka ciekawych helperów akcji. Jeden z nich opisałem we wpisie zatytułowanym Zend Framework i AjaxContext. Innym ciekawym helperem jest FlashMessenger.

Jego działanie polega na jednokrotnym wyświetleniu użytkownikowi wiadomości o pewnym zdarzeniu, np pomyślnym zapisaniu danych w bazie. Po odświeżeniu strony z wiadomością, nie zostanie ona wyświetlona ponownie (chyba że znów będzie miało miejsce odpowiednie zdarzenie).

Korzystanie z FlashMessengera jest bardzo proste i sprowadza się do kilku linii kodu.

class JakisController extends Zend_Controller_Action
{
	protected $_flashMessenger = null;

	public function init()
	{
		// inicjalizacja helpera
		$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
	}

	public function indexAction()
	{
		// pobranie wiadomości błyskawicznych i przekazanie ich do widoku
		$this->view->messages = $this->_flashMessenger->getMessages();
	}

	public function editAction()
	{
		// dodanie wiadomości
		$this->_flashMessenger->addMessage('Treść wiadomości błyskawicznej');
	}
}

Samo wyświetlenie wiadomości w widoku jest banalnie proste

<?php if(count($this->messages) > 0): ?>
	<ul id="messages">
		<?php foreach($this->messages as $message): ?>
			<li><?php echo $message; ?>
		<?php endforeach; ?>
	</li></ul>
<?php endif; ?>

Powyższy kod to tylko przykład. Najlepszym rozwiązaniem będzie zamieszczenie go w helperze widoku.

W niektórych przypadkach obraz wart jest więcej niż tysiąc słów. Tak jest też w tym przypadku. Demo wiadomości błyskawicznych możecie zobaczyć pod adresem http://demo.wilgucki.pl/flashmessenger

Autor wpisu: batman, dodany: 10.06.2010 11:28, tagi: zend_framework

W jednym z poprzednich wpisów poświęconych Zend_Form opisałem sposób dekorowania formularzy w Zend Framework. Niestety poważną wadą tej metody było powtarzanie kodu, co w przypadku rozbudowanej aplikacji nie jest najlepszym pomysłem. Dobrym wyjściem z tej sytuacji będzie zastosowanie klasy bazowej dla naszych formularzy, dziedziczącej po Zend_Form. Klasa ta będzie odpowiedzialna za ustawienie dekoratorów oraz wyrenderowanie formularza.

Przykładowy formularz wygląda następująco

class Application_Form_Example extends Batman_Form
{
	protected function _renderForm()
	{
		$this->setName('form-example');

		$name = new Zend_Form_Element_Text('name');
		$name->setLabel('Nazwa');
		
		$submit = new Zend_Form_Element_Submit('btn_save');
		$submit->setLabel('Zapisz');
		
		$this->addElement($name);
		$this->addElement($submit);
	}
}

Jak widać jedyną różnicą w stosunku do standardowego podejścia jest zmiana nazwy metody, w której znajduje się kod odpowiedzialny za formularz. Ponadto metoda ta nie zawiera kodu odpowiedzialnego za dekoratory.

Cała magia dzieje się w klasie Batman_Form

abstract class Batman_Form extends Zend_Form
{
	abstract protected function _renderForm();
	
	public function init()
	{
		$this->_renderForm();
		$this->_resetDecorators();
	}
	
	protected function _resetDecorators()
	{
		$this->clearDecorators();
		$this->addDecorator('FormElements')
			 ->addDecorator('HtmlTag', array('tag' => 'div'))
			 ->addDecorator('Form');

		$this->setElementDecorators(array(
			array('ViewHelper'),
			array('Errors'),
			array('Label'),
			array('HtmlTag', array('tag' => 'div', 'class' => 'element-group'))
		));
        
		// dodatkowe operacje na konkretnych elementach formularza
		// np zmiana nazwy klasy css dla przycisków
		foreach($this->getElements() as $element) {
			if($element instanceof Zend_Form_Element_Submit) {
				$element->removeDecorator('Label');
				$element->addDecorator('HtmlTag', array('tag' => 'div', 'class' => 'submit-group'));
			}
		}
	}
}

Klasa przesłania metodę init, która jest wywoływana z konstruktora Zend_Form. W metodzie tej wywoływana jest z kolei metoda klasy potomka o nazwie _renderForm oraz metoda _resetDecorators. Konstrukcja ta posiada dwie zalety. Po pierwsze klasa formularza odpowiada jedynie za utworzenie elementów. Po drugie nie musimy powielać kodu odpowiedzialnego za dekoratory. Dla zachowania porządku oraz dla zapewnienia poprawności kodu, klasa Batman_Form jest klasą abstrakcyjną, zawierającą abstrakcyjną metodę _renderForm.

A co jeśli w jednym formularzu mają być użyte inne dekoratory? Nic prostszego. Wystarczy w klasie formularza przesłonić metodę _resetDecorators i napisać własny kod odpowiedzialny za dekoratory.

Autor wpisu: Śpiechu, dodany: 06.06.2010 22:52, tagi: php, zend_framework

Na stronie Zend Framework macie podane konwencje/standardy dotyczące formatowania kodu, nazewnictwa i dokumentacji. Chciałbym pewne rzeczy rozszerzyć w oparciu o własne obserwacje kodu ZF i zalecenia twórców/ekspertów (głównie z ich blogów). Nie będę oczywiście bawił się w tłumacza. Mam nadzieję, że ten 3 częściowy wpis się komuś przyda. Dzielę go z braku czasu… 1. Formatowanie [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.