<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>APEL core</title>
    <link>http://xp-dev.com/tracking/67486</link>
    <description>APEL core</description>
    <pubDate>Sun, 12 Feb 2012 04:28:38 GMT</pubDate>
    <dc:creator>janf0</dc:creator>
    <dc:date>2012-02-12T04:28:38Z</dc:date>
    <item>
      <title>Wiki: Baza danych</title>
      <link>http://xp-dev.com/wiki/67486/Baza%20danych</link>
      <description>&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Poczeniedobazy"&gt;Połączenie do bazy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Klasaapdb"&gt;Klasa ap_db&lt;/a&gt;&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#query"&gt;query&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#fetch"&gt;fetch&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#insert"&gt;insert&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#update"&gt;update&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#delete"&gt;delete&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#begincommitrollback"&gt;begin, commit, rollback&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Wiemy już jak wyświetlić statyczny tekst w naszej aplikacji. Przydałoby się teraz abyśmy mogli wyświetlać treści dynamicznie, aby móc je modyfikować bez ingerencji w kod. Aby otrzymać taką funkcjonalność musimy podłączyć nasz system do bazy danych. Na początek spróbujmy dodać do naszej strony menu w którym możemy włączać i wyłączać z bazy poszczególne zakładki. &lt;/p&gt;&lt;p&gt;Po pierwsze musimy posiadać dostęp do jakiejś bazy danych. Załóżmy że mamy dostęp do bazy danych o następujących parametrach: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;serwer: mojserwer.edu.pl &lt;/li&gt;&lt;li&gt;port: 3306 &lt;/li&gt;&lt;li&gt;login: moj_login &lt;/li&gt;&lt;li&gt;hasło: moje_haslo123 &lt;/li&gt;&lt;li&gt;nazwa bazy: mojapel_baza &lt;/li&gt;&lt;/ul&gt;&lt;h3 id="Poczeniedobazy"&gt;Połączenie do bazy&lt;/h3&gt;&lt;p&gt;W pliku konfiguracyjnym musimy zarejestrować połączenie do tej bazy. Robimy to w następujący sposób: &lt;/p&gt;&lt;pre&gt;....
ap_page::setBase('default','mysql://moj_login:moje_haslo@mojserwer.edu.pl:3306/mojapel_baza/head_');
....

&lt;/pre&gt;&lt;p&gt;Pierwszy argument metody setBase to nazwa połączenia. Dzięki temu parametrowi możemy w systemie łączyć się do kilku różnych baz. Nazwy połączeń mogą być dowolne, jednak przynajmniej jedno powinno nazywać się default &amp;#8211; oznacza to połączenie domyślne. Ostatni fragment &lt;code&gt;head_&lt;/code&gt; oznacza nagłówek wszystkich tabel jakich bedziemy używać we frameworku &amp;#8211; umożliwia to łączenie frameworka z innymi aplikacjami php. Nagłówek jest całkowicie pomijany w klasach (nie uwzględniamy go tworząc nazwy pól i kluczy)&lt;/p&gt;&lt;h3 id="Klasaapdb"&gt;Klasa ap_db&lt;/h3&gt;&lt;p&gt;Za obsługę baz danych odpowiada klasa ap_db. Na chwilę obecną system nie ma zaimplementowanej obsługi innego typu bazy jak mySql, jednak w przyszłości będzie taką funkcjonalność posiadał. Możemy jednak przyjąć że obiektów tej klasy używa się zawsze tak samo, niezależnie od typu bazy. &lt;/p&gt;&lt;p&gt;Klasa ma zaimplementowane następujące metody: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;query('zapytanie sql','nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;fetch('nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;insert('nazwa_tabeli','tablica_pól','nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;update('nazwa_tabeli','nowe_wartości','warunek','nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;delete('nazwa_tabeli','warunek','nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;begin('nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;commit('nazwa_połączenia');&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;rollback('nazwa_połączenia');&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Omówimy teraz poszczególne metody: &lt;/p&gt;&lt;h5 id="query"&gt;query&lt;/h5&gt;&lt;p&gt;Metoda kieruje zapytanie do bazy. Standardowo jest używana do tworzenia zapytań &lt;code&gt;SELECT....&lt;/code&gt;, możemy jednak jej użyć to wszelkiego typu zapytań. Nazwa_połączenia informuje nas do której bazy odnosi się zapytanie. Gdy parametr ten nie jest podany, zapytanie jest adresowane do bazy zdefiniowanej w połączeniu nazwanym default. Ten warunek odnosi się do wszystkich metod, więc nie będziemy go więcej podawać. &lt;/p&gt;&lt;h5 id="fetch"&gt;fetch&lt;/h5&gt;&lt;p&gt;Po wykonaniu querychcielibyśmy otrzymać jakieś wyniki. Umożliwia nam to funkcja fetch która kolejno zwraca rekordy będące wynikiem zapytania. Jeśli zwrócono już wszystkie rekordy, lub wynik zapytania jest pusty, metoda zwraca null. Wyniki są zwracane w postaci tablicy asocjacyjnej w której kluczem jest nazwa pola tabeli, a wartością zawartość pola w bazie. &lt;/p&gt;&lt;h5 id="insert"&gt;insert&lt;/h5&gt;&lt;p&gt;Metoda dodaje do tabeli nazwa_tabeli nowy rekord i zwraca jego id(id to &lt;code&gt;PRIMARY KEY&lt;/code&gt;). Dane do zapisania, czyli tablica_pól, powinna być w formie tablicy asocjacyjnej gdzie kluczem jest nazwa pola, a wartością dana jaką na tym polu chcemy zapisać. &lt;/p&gt;&lt;h5 id="update"&gt;update&lt;/h5&gt;&lt;p&gt;Uaktualnienie rekordu w tabeli. Wartości do zapisania powinny być w tablicy asocjacyjnej, natomiast warunek może być w postaci albo tablicy asocjacyjnej, albo tekstowej. &lt;/p&gt;&lt;p&gt;&lt;i&gt;Przykład:&lt;/i&gt; &lt;/p&gt;&lt;pre&gt;// oba zapisy są równoważne

$db-&amp;gt;update('jakas_tabela',array('poleUpdate'=&amp;gt;'nowa_wartość'),array('klucz'=&amp;gt;'id_klucza'));

$db-&amp;gt;update('jakas_tabela',array('poleUpdate'=&amp;gt;'nowa_wartość'),'klucz = id_klucza');

&lt;/pre&gt;&lt;p&gt;Postać tekstowa warunku umożliwia nam wprowadzanie klauzul postaci &lt;code&gt;a &amp;gt; b, a in (a,b,c)&lt;/code&gt;  itp. &lt;/p&gt;&lt;h5 id="delete"&gt;delete&lt;/h5&gt;&lt;p&gt;Usuwa rekordy z bazy spełniające podany warunek. Postać warunku taka jak przy update &lt;/p&gt;&lt;h5 id="begincommitrollback"&gt;begin, commit, rollback&lt;/h5&gt;&lt;p&gt;Metody służące do zapewnienia transakcyjności. &lt;/p&gt;&lt;p&gt;Przyjmuje się że bezpośrednie odwołania do bazy przez obiekty klasy &lt;code&gt;ap_db&lt;/code&gt; powinny znajdować się wyłącznie w managerach i obiektach (&lt;code&gt;ap_obj&lt;/code&gt;), jednak nie jest błędem ich użycie w innych miejscach, zwłaszcza gdy chodzi o optymalizację. Może to jednak skutkować pogorszeniem czytelności programu i późniejszymi problemami przy rozbudowie lub zmianach w aplikacji.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Widok"&gt;&amp;lt;&amp;lt;&amp;lt; Widok&lt;/a&gt; - &lt;a href="http://www.xp-dev.com/wiki/67486/Pierwsze%20kroki"&gt;Pierwsze kroki &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:04:48 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Baza%20danych</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:04:48Z</dc:date>
    </item>
    <item>
      <title>Wiki: Homepage</title>
      <link>http://xp-dev.com/wiki/67486/Homepage</link>
      <description>&lt;p&gt;Opis fameworku APEL który kiedyś miałem zrobiony na moodle&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Opis%20frameworku"&gt;Opis frameworku&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Obiekty"&gt;Obiekty&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Kontroler"&gt;Kontroler&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Widok"&gt;Widok&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Baza%20danych"&gt;Baza danych&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Pierwsze%20kroki"&gt;Pierwsze kroki&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>
      <pubDate>Mon, 16 May 2011 09:58:23 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Homepage</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T09:58:23Z</dc:date>
    </item>
    <item>
      <title>Wiki: Kontroler</title>
      <link>http://xp-dev.com/wiki/67486/Kontroler</link>
      <description>&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Parametrykontrolera"&gt;Parametry kontrolera&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#nativeShow"&gt;$nativeShow&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#actions"&gt;$actions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Metodyuywanewkontrolerze"&gt;Metody używane w kontrolerze&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Z poprzednich lekcji wiemy już nieco o klasach występujących w APELU, zasadach tworzenia nazw tabel oraz obiektów. Pora przejść do szczegółowych opisów poszczególnych klas. Opis zrobimy na przykładzie naszego systemu mojapel którego szkielet przygotowaliśmy na pierwszej lekcji. Co zrobić aby móc cokolwiek wyświetlić na ekranie? Po pierwsze musimy zdefiniować domyślny kontroler dla naszego systemu. Zwyczajowo nazywany jest &lt;code&gt;ctrl_main&lt;/code&gt;, tak więc nie będziemy odbiegać od tej zasady. &lt;/p&gt;&lt;h3 id="Parametrykontrolera"&gt;Parametry kontrolera&lt;/h3&gt;&lt;p&gt;Aby dokładnie omówić działanie kontrolera, musimy zacząć od tego jak działa najważniejszy obiekt sterujący w systemie, czyli obiekt klasy &lt;code&gt;ap_page&lt;/code&gt; zdefiniowany w pliku &lt;code&gt;front/index.php&lt;/code&gt;. Odpowiada on za całość działania aplikacji, czyli ładowanie odpowiedniego kontrolera, renderowanie strony html, obsługę błędów i ładowania plików. Obiekt ten rozpoznaje który kontroler załadować na podstawie parametru przekazywanego w adresie URL strony, a konkretnie switch, i przekazuje do niego nazwę metody jaką kontroler ma wywołać (parametr &lt;code&gt;action&lt;/code&gt;). W konstruktorze obiektu jest zdefiniowana tablica &lt;code&gt;$this-&amp;gt;ctrl&lt;/code&gt; w której kluczem jest wartość parametru switch a wartością nazwa kontrolera do załadowania. Tabela musi zawierać conajmniej jedną pozycję, i musi to być kontroler przypisany do parametru default. Zostanie on załadowany gdy wywołamy adres strony beż żadnego parametru. Przejdźmy teraz do samego kontrolera. W kontrolerze są zawarte trzy parametry które musimy wypełnić. Są to: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;$defaultAction&lt;/code&gt; - nazwa metody jaka zostanie wywołana przy załadowaniu strony bez zdefiniowanego parametru action &lt;/li&gt;&lt;li&gt;&lt;code&gt;$nativeShow&lt;/code&gt; - nazwa domyślnego widoku jaki wyświetli kontroler &lt;/li&gt;&lt;li&gt;&lt;code&gt;$actions&lt;/code&gt; - tablica ze zdefiniowanymi nazwami metod które ma prawo wywołać użytkownik z parametru action &lt;/li&gt;&lt;li&gt;&lt;code&gt;$defaultAction&lt;/code&gt; - na tą zmienną przypisujemy jeden z kluczy tablicy $actions. Będzie on nam definiował metodę jaka zostanie wybrana gdy w adresie URL zostanie pominięty lub nie wypełniony parametr action. Pole jest obowiązkowe. &lt;/li&gt;&lt;/ul&gt;&lt;h3 id="nativeShow"&gt;$nativeShow&lt;/h3&gt;&lt;p&gt;Kontrolery są odpowiedzialne za składanie stron html &amp;#8220;do kupy&amp;#8221;, czyli generowanie stron. Ponieważ zawsze coś musi zostać wyświetlone, każdy kontroler posiada widok natywny, który jest wypełniany treścią w zależności od wywołanej metody. Omówmy to na przykłądzie: &lt;/p&gt;&lt;p&gt;Każda strona internetowa musi posiadać przynajmniej taki zestaw tagów: &lt;/p&gt;&lt;pre&gt;&amp;lt;html&amp;gt;
	&amp;lt;head&amp;gt;
	&amp;lt;/head&amp;gt;
	&amp;lt;body&amp;gt;
	&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;p&gt;W nagłówku powinniśmy jeszcze umieścić informacje o kodowaniu, opis strony (czyli znaczniki meta), tytuł strony, często dodajemy informacje o stylach czy kody javascript. Dodawanie tego za każdym razem do strony jest zwykłą stratą czasu, dlatego też najwygodniej jest niezmienne części strony umieścić w jednym miejscu aby ich za każdym razem nie przepisywać, natomiast modyfikować tylko to co się zmienia. Właśnie widok natywny jest takim kontenerem który jest niezmienny, a do niego doładowywane są obiekty generujące odpowiednie fragmenty strony. Dokładnie opiszemy ten mechanizm nieco później. &lt;/p&gt;&lt;h3 id="actions"&gt;$actions&lt;/h3&gt;&lt;p&gt;Ta zmienna jest tablicą w której mamy nazwy metod uprawnionych do wywołania przez parametr action. Została ona wprowadzona w celu zabezpieczenia systemu przed próbą ataku polegającą na dopasowywaniu parametrów adresu URL. W tablicy tej kluczem jest wartość parametru action a wartością nazwa wywoływanej metody. Z reguły są one jednakowe. &lt;/p&gt;&lt;h3 id="Metodyuywanewkontrolerze"&gt;Metody używane w kontrolerze&lt;/h3&gt;&lt;p&gt;Jak już się dowiedzieliśmy wcześniej kontroler odpowiada za interakcję z użytkownikiem, i złożenie wynikowej strony html, zatem musi otrzymać jakieś dane wejściowe, dokonać na nich jakichś operacji i na końcu odpowiednio zbudować stronę do wyświetlenia. Do tych wszystkich czynności służy zestaw predefiniowanych metod: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;get('param_name')&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;set('param_name')&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;addShow('show_name','position')&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;addMngr('mngr_name')&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Metoda &lt;code&gt;get&lt;/code&gt; pobiera wartość parametru param_name. Metoda set ustawia ją. Metoda addMngr tworzy nam nowego managera o nazwie &lt;code&gt;mngr_name&lt;/code&gt; i zwraca do niego wskaźnik. Podobnie czyni metoda &lt;code&gt;addShow&lt;/code&gt; z tym że dotyczy widoków i posiada parametr position który mówi nam o tym w którym miejscu widoku natywnego mamy dany widok umieścić. &lt;/p&gt;&lt;p&gt;Posiadając już taką wiedzę spróbujmy stworzyć własny kontroler. Tworzymy plik &lt;code&gt;front/system/ctrl/main.php&lt;/code&gt; i umieszczamy w nim definicję klasy &lt;code&gt;ctrl_main&lt;/code&gt;. Następnie musimy w nim określić domyślną akcję, listę metod uprawnionych oraz nazwę natywnego widoku. Przyjmijmy że domyślny widok będzie nazywał się &lt;code&gt;show_main&lt;/code&gt; a domyślna metoda &lt;code&gt;show&lt;/code&gt;. W tym momencie nasz kontroler powinien wyglądać mniej więcej tak: &lt;/p&gt;&lt;pre&gt;/**
 *  przykładowy kontroler
 */
class ctrl_main extends ap_ctrl implements iface_ctrl {
	protected $defaultAction = 'show';
	protected $nativeShow = 'show_main';
	protected $actions = array (
		'show' =&amp;gt; 'show'
	);
	public function show() {
	
	}
}

&lt;/pre&gt;&lt;p&gt;Jak widać ciało metody show jest jeszcze nie wypełnione, jednak jeszcze za mało umiemy aby móc je wypełnić.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Obiekty"&gt;&amp;lt;&amp;lt;&amp;lt; Obiekty&lt;/a&gt; - &lt;a href="http://www.xp-dev.com/wiki/67486/Widok"&gt;Widok &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:02:46 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Kontroler</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:02:46Z</dc:date>
    </item>
    <item>
      <title>Wiki: Obiekty</title>
      <link>http://xp-dev.com/wiki/67486/Obiekty</link>
      <description>&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Zasadynazewnictwa"&gt;Zasady nazewnictwa&lt;/a&gt;&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Bazadanych"&gt;Baza danych&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Klasy"&gt;Klasy&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Typyobiektw"&gt;Typy obiektów&lt;/a&gt;&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Kontroleryobiektyklasyapctrl"&gt;Kontrolery (obiekty klasy ap_ctrl)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Widokiobiektyklasyapshow"&gt;Widoki (obiekty klasy ap_show)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Manageryobiektyklasyapmngr"&gt;Managery (obiekty klasy ap_mngr)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Obiektyobiektyklasyapobj"&gt;Obiekty (obiekty klasy ap_obj)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Klasysystemowe"&gt;Klasy systemowe&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 id="Zasadynazewnictwa"&gt;Zasady nazewnictwa&lt;/h3&gt;&lt;p&gt;Aby w pełni wykorzystać mechanizmy zaimplementowane we frameworku musimy przestrzegać kilku zasad: &lt;/p&gt;&lt;h5 id="Bazadanych"&gt;Baza danych&lt;/h5&gt;&lt;p&gt;Tabele w bazie powinny być nazywane w formacie nazwa_tabeli. Każda z tabel powinna posiadać klucz &lt;code&gt;PRIMARY&lt;/code&gt; o nazwie &lt;code&gt;nazwaTabeliId&lt;/code&gt;. Jest to bardzo ważne gdyż zachowując taki format obiekty frameworku są w stanie automatycznie rozpoznać klucz główny tabeli i zautomatyzować operacje na bazie. Jeśli nie zachowamy takiego formatu nazewnictwa tabel, operacje odczytu i zapisu do tabeli będziemy musieli definiować sami. &lt;/p&gt;&lt;h5 id="Klasy"&gt;Klasy&lt;/h5&gt;&lt;p&gt;Nazwa każdej klasy powinna być w formacie moja_nazwa_klasy, a jej definicja powinna znajdować się w katalogu &lt;code&gt;system/moja/nazwa/klasy.php&lt;/code&gt;. W przypadku gdy nie zachowamy takiego formatu będziemy musieli jawnie używać instrukcji include bądź require. &lt;/p&gt;&lt;h3 id="Typyobiektw"&gt;Typy obiektów&lt;/h3&gt;&lt;p&gt;Do tworzenia aplikacji w oparciu o framework APEL używa się czterech typów obiektów. Są to: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;kontrolery (dziedziczą po ap_ctrl) &lt;/li&gt;&lt;li&gt;widoki (dziedziczą po ap_show) &lt;/li&gt;&lt;li&gt;managery (dziedziczą po ap_mngr) &lt;/li&gt;&lt;li&gt;obiekty (dziedziczą po ap_obj) &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Dodatkowo zostały zaimplementowane klasy tzw. systemowe służące np. do obsługi przekazywanych przez serwer zmiennych lub mechanizmu cache (&lt;code&gt;ap_var&lt;/code&gt; oraz &lt;code&gt;ap_cache&lt;/code&gt;). Ich omówieniem zajmiemy się później, teraz zajmijmy się typami obiektów opisanymi powyżej. &lt;/p&gt;&lt;h5 id="Kontroleryobiektyklasyapctrl"&gt;Kontrolery (obiekty klasy ap_ctrl)&lt;/h5&gt;&lt;p&gt;Obiekty tego typu odpowiadają za interakcję z użytkownikiem. Odbierają parametry i dokonują operacji na obiektach. Są również odpowiedzialne za umieszczanie widoków na stronie. Kontrolery implementujemy w katalogu &lt;code&gt;system/ctrl&lt;/code&gt;. Tworząc nową aplikację powinniśmy na początku zdefiniować kontroler domyślny, czyli taki który będzie się uruchamiał przy wejściu na stronę główną naszego serwisu. Zwyczajowo nazywa się go &lt;code&gt;ctrl_main&lt;/code&gt; i jego definicję umieszcza się w pliku &lt;code&gt;system/ctrl/main.php&lt;/code&gt;. &lt;/p&gt;&lt;h5 id="Widokiobiektyklasyapshow"&gt;Widoki (obiekty klasy ap_show)&lt;/h5&gt;&lt;p&gt;Widoki generują nam fragmenty strony html. Każdy kontroler ma swój widok domyślny, nie ma jednak wymogu aby dla każdego z nich był inny. W szczególności wszystkie kontrolery mogą mieć ten sam widok domyślny i będzie to najczęściej spotykana sytuacja. Widoki można w sobie zagnieżdżać (dokładnie ten proces omówimy w dalszej części kursu). Do każdego widoku jest przypisany szablon smarty z którego generuje on kod HTML. Implementujemy je w katalogu &lt;code&gt;system/show&lt;/code&gt;.&lt;/p&gt;&lt;h5 id="Manageryobiektyklasyapmngr"&gt;Managery (obiekty klasy ap_mngr)&lt;/h5&gt;&lt;p&gt;Managery są obiektami odwołującymi się już bezpośrednio do bazy danych, jednakże służą raczej do operacji grupowych na tabelach. Przy użyciu managerów możemy filtrować i wyszukiwać dane z bazy. Każdy manager ma przypisany do siebie obiekt klasy &lt;code&gt;ap_obj&lt;/code&gt; który zawiera informację o tabeli w bazie danych, dlatego też praktykuje się nazywanie managerów tak aby jednoznacznie kojarzyły się z obiektami i odpowiadającymi im tabelami. Trzymanie się tej zasady bardzo ułatwia zrozumienie kodu i może ograniczyć ewentualne błędy (od razu możemy skojarzyć jakiej tabeli i jakiego obiektu dotyczy manager na podstawie tylko jego nazwy). Managery implementuje się w katalogu &lt;code&gt;system/mngr&lt;/code&gt;&lt;/p&gt;&lt;h5 id="Obiektyobiektyklasyapobj"&gt;Obiekty (obiekty klasy ap_obj)&lt;/h5&gt;&lt;p&gt;Najprościej mówiąc pojedynczy obiekt tej klasy odpowiada pojedynczemu rekordowi w tabeli bazy danych. Obiekty tej klasy mają zaimplementowane automatyczne dodawanie oraz aktualizację informacji w bazie. Dobrą praktyką jest nazywanie obiektu podobnie jak nazywa się tabela w bazie do której się on odnosi, czyli tabeli o nazwie &lt;code&gt;moja_tabela&lt;/code&gt; powinien odpowiedać obiekt &lt;code&gt;obj_moja_tabela&lt;/code&gt;. &lt;/p&gt;&lt;h5 id="Klasysystemowe"&gt;Klasy systemowe&lt;/h5&gt;&lt;p&gt;Część operacji taka jak komunikacja z bazą danych, z cache czy też wysyłanie e-maili została zaimplementowana w tzw. klasach systemowych. Ich używanie nie jest wymagane, jednakże stanowią one spójną całość z resztą frameworku i ich użycie jest bardzo zalecane. Są to klasy &lt;code&gt;ap_bd&lt;/code&gt;, &lt;code&gt;ap_cache&lt;/code&gt; czy &lt;code&gt;ap_mail&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Opis%20frameworku"&gt;&amp;lt;&amp;lt;&amp;lt; Opis frameworku&lt;/a&gt; - &lt;a href="http://www.xp-dev.com/wiki/67486/Kontroler"&gt;Kontroler &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:01:40 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Obiekty</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:01:40Z</dc:date>
    </item>
    <item>
      <title>Wiki: Opis frameworku</title>
      <link>http://xp-dev.com/wiki/67486/Opis%20frameworku</link>
      <description>&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Czymjestframework"&gt;Czym jest framework&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Strukturaplikw"&gt;Struktura plików&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#config"&gt;config&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#out"&gt;out&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#skin"&gt;skin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#system"&gt;system&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#index.php"&gt;index.php&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 id="Czymjestframework"&gt;Czym jest framework&lt;/h3&gt;&lt;p&gt;Najprościej mówiąc framework jest to narzędzie służące do tworzenia aplikacji. Jego użycie sprawia że praca programisty jest łatwiejsza i szybsza, a sama aplikacja posiada mniej błędów. W tym celu powstał również framework dla systemu APEL, jest on jednak na tyle uniwersalny, że można go wykorzystać do budowy dowolnej aplikacji. Z poniższego kursu dowiemy się jak w oparciu o niego zbudować własny system, oraz jak używać mechanizmów w nim zawartych. &lt;/p&gt;&lt;h3 id="Strukturaplikw"&gt;Struktura plików&lt;/h3&gt;&lt;p&gt;Używanie frameworku najprościej będzie omówić na przykładzie. Załóżmy że chcemy zbudować własny system którego roboczo nazwiemy mojapel. Od czego należy zacząć? &lt;br/&gt; Po pierwsze należy przygotować odpowiednią strukturę plików dla naszego systemu. Tworzymy katalog mojapel w którym będzie znajdował się kod naszego systemu. Teraz musimy stworzyć dwa podkatalogi: w pierwszym będą się znajdować pliki naszego frameworku (zwyczajowo jest on nazywany core) oraz drugi w którym będzie znajdować się kod napisany przez nas (nazwijmy go front). &lt;/p&gt;&lt;p&gt;Zazwyczaj plików w katalogu core nie modyfikujemy. Oczywiście jest to możliwe ale może spowodować problemy przy aktualizacji wersji frameworku, więc lepiej tego nie robić&lt;/p&gt;&lt;p&gt;Zajmijmy się więc drzewem plików katalogu front. Powinny się w nim znaleźć następujące podkatalogi: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;config &lt;/li&gt;&lt;li&gt;out&lt;/li&gt;&lt;li&gt;skin &lt;/li&gt;&lt;li&gt;system&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Omówimy teraz co powinno się znajdować w każdym z katalogów&lt;/p&gt;&lt;h3 id="config"&gt;config&lt;/h3&gt;&lt;p&gt;Katalog config jest miejscem na pliki konfiguracyjne. Przy tworzeniu oprogramowania prawie zawsze ustawienia deweloperskie różnią się od ustawień produkcyjnych. Zmusza to programistę do utrzymywania różnych wersji pliku konfiguracyjnego, lub ciągłej jego edycji co bywa dosyć uciążliwe i może skutkować wystąpieniem błędów wynikających np. z wyeksportowania na serwer produkcyjny pliku konfiguracyjnego z serwera testowego. W naszym frameworku przewidziano istnienie różnych plików konfiguracyjnych, zmienianych jedynie przy pomocy jednej flagi w systemie (można się nawet pokusić o automatyzację wyboru na podstawie np. IP serwera). Na potrzeby tworzenia aplikacji używamy pliku test.php natomiast po wdrożeniu work.php. &lt;/p&gt;&lt;p&gt;&lt;b&gt;UWAGA! Pliki muszą się nazywać dokładnie tak jak podano powyżej, inaczej nie zostaną one rozpoznane.&lt;/b&gt;&lt;/p&gt;&lt;h3 id="out"&gt;out&lt;/h3&gt;&lt;p&gt;W tym katalogu serwer będzie zapisywał potrzebne mu pliki tymczasowe. Znajdą się w nim pliki cache, logi, możemy też używać go do zapisu innych potrzebnych nam rzeczy. Drzewo katalogów wewnątrz katalogu out powinno wyglądać następująco: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;cache &lt;ul&gt;&lt;li&gt;cache &lt;/li&gt;&lt;li&gt;compile &lt;/li&gt;&lt;li&gt;config &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;log &lt;ul&gt;&lt;li&gt;exception &lt;/li&gt;&lt;li&gt;logs &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Podkatalog cache będzie używany przez mechanizm smarty na którym oparte jest generowanie stron naszego frameworka, natomiast w katalogu log znajdą się wszelkiego rodzaju logi generowane przez system. Oprócz wyżej wymienionych możemy oczywiście dodać własne w miarę potrzeb. Trzeba jedynie pamiętać że wszystkie muszą mieć uprawnienia do zapisu przez serwer.&lt;/p&gt;&lt;h3 id="skin"&gt;skin&lt;/h3&gt;&lt;p&gt;Tutaj będą znajdowały się &amp;#8220;skórki&amp;#8221; naszego systemu. Możemy ich zdefiniować większą ilość i używać w dowolny sposób, muszą jednak mieć określoną strukturę. Bezpośrednio w katalogu skin powinien znaleźć się katalog którego nazwa jest nazwą naszej &amp;#8220;skóry&amp;#8221;. Domyślnie jest to katalog default. W nim muszą znaleźć się katalogi mail gdzie będą zdefiniowane szablony dla emaili wychodzących z systemu, oraz template gdzie znajdują się szablony html (zapisane w formacie smarty z rozszerzeniem .tpl. Na tym poziomie możemy też zdefiniować pliki css oraz javascript. Co do ich umiejscowienia nie ma określonych wymogów (ścieżkę do nich podajemy w szablonie strony). Tutaj też powinna znaleźć się grafika używana na stronie (zwyczajowo katalog z grafiką nazywamy images) &lt;/p&gt;&lt;h3 id="system"&gt;system&lt;/h3&gt;&lt;p&gt;Ten katalog jest z naszego punktu widzenia najważniejszy. W nim będą znajdować się definicje wszystkich używanych przez nas obiektów. Powinny się w nim znaleźć cztery podkatalogi: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;ctrl &lt;/li&gt;&lt;li&gt;show &lt;/li&gt;&lt;li&gt;mngr &lt;/li&gt;&lt;li&gt;obj &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Co oznaczają ich nazwy i do czego służą dowiemy się z następnych lekcji. W katalogu tym znajduje się też bardzo ważny plik exception.php. Jest on odpowiedzialny za obsługę wyjątków w naszym systemie. Jeśli nie chcemy tworzyć własnej ich obsługi (a na razie nie chcemy) wystarczy że użyjemy standardowo zdefiniowanej klasy wyjątków. W takim przypadku plik exception.php będzie wyglądał tak: &lt;/p&gt;&lt;pre&gt;&amp;lt;?
/**
 * Exceptions
 */
class system_exception extends ap_exception {

}
?&amp;gt;

&lt;/pre&gt;&lt;h3 id="index.php"&gt;index.php&lt;/h3&gt;&lt;p&gt;Teraz zajmijmy się głównym plikiem naszego systemu, czyli index.php. Na samym początku tworzenia naszej aplikacji powinien wyglądać tak: &lt;/p&gt;&lt;pre&gt;&amp;lt;?
/**
 * Main class 
 */
date_default_timezone_set('Europe/Warsaw');
session_start();
require_once('../core/ap/page.php');

/**
 *  klasa odpowiedzialna za wyświetlanie stron serwisu
 */
class mojapel extends ap_page {

    /**
     *  inicjalizacja zmiennych systemowych
     */
    protected $skin = 'default';
    
    protected function init() {
        self::$context = ap_sys::PROFILE_TEST;
        $this-&amp;gt;ctrl = array ();
    }

}
try {
    $page  = new mojapel();
    $page-&amp;gt;display();
} catch (system_exception $xt) {
    $xt-&amp;gt;catchIt();
}

?&amp;gt;

&lt;/pre&gt;&lt;p&gt;Zwróćmy uwagę na zmienne $skin i $context. Jak widać modyfikując je możemy zmieniać tryb działania aplikacji (testowy/produkcyjny) jak również wybrać layout. Do przełączenia trybu działania używamy dwóch stałych: &lt;/p&gt;&lt;pre&gt;ap_sys::PROFILE_TEST 
ap_sys::PROFILE_WORK 

&lt;/pre&gt;&lt;p&gt;W zależności od tego którą przypiszemy, taki typ pliku konfiguracyjnego zostanie włączony do aplikacji. &lt;/p&gt;&lt;p&gt;Aby zmienić layout naszej strony wystarczy na zmienną $skin przypisać nazwę katalogu w jakim go zdefiniowaliśmy. &lt;/p&gt;&lt;p&gt;Tak oto dobrnęliśmy do końca przygotowań. Możemy przystąpić do implementacji naszego systemu. &lt;/p&gt;&lt;p&gt;W praktyce nie musimy pamiętać całej struktury i za każdym razem samemu ją tworzyć. W katalogu core/start/ znajduje się plik start.zip w którym znajduje się spakowana gotowa struktura katalogu użytkownika (u nas front). W naszym przykładzie wystarczyłoby do katalogu front rozpakować ten plik i ewentualnie zmienić prawa dostępu do katalogu out wraz z podkatalogami.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Obiekty"&gt;Obiekty &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:00:16 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Opis%20frameworku</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:00:16Z</dc:date>
    </item>
    <item>
      <title>Wiki: Pierwsze kroki</title>
      <link>http://xp-dev.com/wiki/67486/Pierwsze%20kroki</link>
      <description>&lt;p&gt;Znamy już metodę podłączenia się do bazy, jak również zasady nazewnictwa tabel i obiektów. Możemy więc przystąpić do tworzenia managerów i ob(j)ektów. Ponieważ managery są bardziej skomplikowane i wykorzystują obiekty (obj) ich omówienie zostawimy na później. Teraz przystąpimy do utworzenia przykładowego obiektu. &lt;/p&gt;&lt;p&gt;Na poprzedniej lekcji zdefiniowaliśmy połączenie do bazy, więc nie musimy się już tym martwić. Załóżmy że chcemy stworzyć i obsługiwać tabelę w której będą się znajdować pozycje menu naszej strony. Nazwijmy ją mojapel_menu. Powinna mieć ona 4 pola: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;mojapelMenuId - (klucz, PRIMARY KEY) &lt;/li&gt;&lt;li&gt;itemActive &amp;#8211; flaga informująca o tym czy dana pozycja menu jest aktywna &lt;/li&gt;&lt;li&gt;menuName &amp;#8211; tekst wyświetlany na danej pozycji menu &lt;/li&gt;&lt;li&gt;menuLink &amp;#8211; link do którego przenosi nas dana pozycja menu &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Gdy stworzyliśmy tabelę tworzymy obiekt jej odpowiadający. Nazwiemy go obj_mojapel_menu. Będzie zaimplementowany w katalogu &lt;code&gt;system/obj/mojapel/menu.php&lt;/code&gt;. Do prawidłowego działania potrzebuje zdefiniowanego parametru $tableName który informuje do jakiej tabeli jest on przypisany. Dodatkowo musimy zdefiniować funkcję validate() która jest odpowiedzialna za sprawdzenie błędów przed zapisem rekordu do bazy. Ostatnią rzeczą są wpisane definicje pól z bazy. Klasa może wyglądać następująco: &lt;/p&gt;&lt;pre&gt;class obj_mojapel_menu extends ap_obj implements iface_obj {
	protected $tableName = 'mojapel_menu';

	protected $fields = array (
		'mojapelMenuId',
		'itemActive',
		'menuName',
		'menuLink,
	);
	protected function validate() {
		if (empty($this-&amp;gt;menuName)) {
			throw new system_exception('Nie wypełniono nazwy menu');
		}
	}
}

&lt;/pre&gt;&lt;p&gt;Klasa jest już gotowa do użytku. Przy użyciu obiektów tej klasy możemy standardowo pobierać pojedyncze rekordy z bazy, jak też zapisywać w nich zmiany. Obiekty same rozpoznają czy zapis jest modyfikacją, czy dodaniem nowego rekordu. &lt;/p&gt;&lt;p&gt;Ustawienie jednego z pól w obiekcie wykonuje się funkcją setNazwaPola. Przykładowo w naszym obiekcie będzie to np.setItemActive. Po dokonaniu zmian musimy wywołać metodę &lt;code&gt;save&lt;/code&gt;, która zapisze zmiany do bazy. Ostatnią ciekawą funkcjonalnością obiektów jest wczytanie wszystkich pól danego rekordu z bazy. Realizuje to metoda  &lt;code&gt;getDetails();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Baza%20danych"&gt;&amp;lt;&amp;lt;&amp;lt; Baza danych&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:05:28 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Pierwsze%20kroki</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:05:28Z</dc:date>
    </item>
    <item>
      <title>Wiki: Widok</title>
      <link>http://xp-dev.com/wiki/67486/Widok</link>
      <description>&lt;ol style="list-style: none;"&gt;&lt;li&gt;&lt;a href="#Parametrywidokuiklasyabstrakcyjne"&gt;Parametry widoku i klasy abstrakcyjne&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Metodyuywanewwidoku"&gt;Metody używane w widoku&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Zagniedaniewidokw"&gt;Zagnieżdżanie widoków&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Na poprzedniej lekcji, przy omawianiu kontrolerów wspomnieliśmy o widokach, a w szczególności o widoku natywnym kontrolera. Na dzisiejszej lekcji przybliżymy sobie dokładniej pojęcie widoku, jego działanie i sposób definiowania. Jak już wiemy, framework APEL generuje strony html w oparciu o mechanizm szablonów smarty. Nie będziemy go tutaj opisywać - dokładny opis tego mechanizmu możemy znaleźć na stronie &lt;a href="http://www.smarty.net/."&gt;http://www.smarty.net/.&lt;/a&gt; Definicje szablonów (co też już omawialiśmy) znajdują się w katalogu front/skin/default/templates/. Co więc trzeba do napisania własnego widoku? &lt;/p&gt;&lt;h3 id="Parametrywidokuiklasyabstrakcyjne"&gt;Parametry widoku i klasy abstrakcyjne&lt;/h3&gt;&lt;p&gt;Do poprawnego zdefiniowania widoku potrzebny jest nam tylko jeden parametr. Nazywa się on &lt;code&gt;$template&lt;/code&gt; i jest to nazwa szablonu smarty który dany widok będzie generował. Jeśli szablon nie jest zdefiniowany bezpośrednio w katalogu templates tylko po drodze są jakieś podkatalogi, musimy podać do niego ścieżkę. Przy nazwie szablonu pomijamy rozszerzenie pliku (.tpl). &lt;/p&gt;&lt;p&gt;Potrzebna jest nam jeszcze definicja funkcji &lt;code&gt;init()&lt;/code&gt;. W niej umieszczamy kod potrzebny do przygotowania danego fragmentu strony. Nie będzie błędem pozostawienie tej metody pustej, i powierzenie przygotowania kontrolerowi, ale może to prowadzić do nadmiernej rozbudowy kontrolera, jak również konieczności wielokrotnego powtarzania kodu, zwłaszcza gdy widoku używamy więcej niż raz. Najprościej ten problem wyjaśnić na przykładzie: &lt;/p&gt;&lt;p&gt;Załóżmy że widok zawiera element &amp;lt;select&amp;gt; w postaci listy rozwijanej. Wybrany element jest przekazywany przez parametr &lt;code&gt;selectedOption&lt;/code&gt; i &lt;code&gt;selectedOption2&lt;/code&gt;. Możemy więc zostawić metodę init() w widoku pustą i wszystko przerzucić do kontrolera, wtedy kod kontrolera i widoku będzie wyglądał tak: (przyjmujemy że widok będzie użyty w dwóch metodach kontrolera: &lt;code&gt;show_1()&lt;/code&gt; i &lt;code&gt;show_2()&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;/**
  * kontroler
  */
	....
  public function show() {
	$options = array (
		'1' =&amp;gt; 'jeden',
		'2' =&amp;gt; 'dwa',
		'3' =&amp;gt; 'trzy'
	);
	$show = $this-&amp;gt;addShow('show_main');
	$opt = $this-&amp;gt;get('selectedOption');
	$show-&amp;gt;assign('options',$options);
	$show-&amp;gt;assign('selectedOptions',$opt);
  }
	.....
  public function show_2() {
	$options = array (
		'1' =&amp;gt; 'jeden',
		'2' =&amp;gt; 'dwa',
		'3' =&amp;gt; 'trzy'
	);
	$show = $this-&amp;gt;addShow('show_main');
	$opt = $this-&amp;gt;get('selectedOption2');
	$show-&amp;gt;assign('options',$options);
	$show-&amp;gt;assign('selectedOptions',$opt);
  }
	.........	 /**
  * widok
  */	
  public function init() {
  }

&lt;/pre&gt;&lt;p&gt;Jak widzimy cały kod musieliśmy powtórzyć dwukrotnie. Teraz to co jest niezmienne przerzućmy do widoku. Wtedy kod będzie wyglądał tak:  &lt;/p&gt;&lt;pre&gt;/**
  * kontroler
  */
	....
  public function show() {
	$show = $this-&amp;gt;addShow('show_main');
	$opt = $this-&amp;gt;get('selectedOption');
	$show-&amp;gt;assign('selectedOptions',$opt);
  }
	.....
  public function show_2() {
	$show = $this-&amp;gt;addShow('show_main');
	$opt = $this-&amp;gt;get('selectedOption2');
	$show-&amp;gt;assign('selectedOptions',$opt);
  }
	.........	 /**
  * widok
  */	
  public function init() {
	$options = array (
		'1' =&amp;gt; 'jeden',
		'2' =&amp;gt; 'dwa',
		'3' =&amp;gt; 'trzy'
	);
	$this-&amp;gt;assign('options',$options);
  }

&lt;/pre&gt;&lt;p&gt;Jak widać można zaoszczędzić sobie sporo pisania. &lt;/p&gt;&lt;h3 id="Metodyuywanewwidoku"&gt;Metody używane w widoku&lt;/h3&gt;&lt;p&gt;Predefiniowane metody używane w widoku to: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;assign(param_name,param_value)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;addMngr('mngr_name')&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code&gt;addShow('show_name','position')&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;initPosition('position')&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;assign&lt;/code&gt; jest to tak naprawdę metoda z mechanizmu smarty, nie wymaga więc opisu; &lt;code&gt;addMngr&lt;/code&gt; i &lt;code&gt;addShow&lt;/code&gt; działają identycznie jak w przypadku kontrolera, natomiast metoda &lt;code&gt;initPosition&lt;/code&gt; jest odpowiedzialna za inicjalizację pozycji &lt;code&gt;position&lt;/code&gt;. O co chodzi z tą inicjalizacją dowiemy się za chwilę. &lt;/p&gt;&lt;h3 id="Zagniedaniewidokw"&gt;Zagnieżdżanie widoków&lt;/h3&gt;&lt;p&gt;Jak już wiemy, kontroler ma za zadanie poskładać z widoków kompletną stronę html. Polega to na tym, że &amp;#8220;zbiera&amp;#8221; od różnych widoków fragmenty wygenerowanego kodu i umieszcza w swym widoku natywnym. Aby mógł to zrobić w szablonie widoku natywnego musimy określić pozycje na których będą się znajdować te fragmenty kodu. Nie są one niczym innym jak zmiennymi smarty. Dodając do widoku, bądź kontrolera kolejny widok musimy określić jego pozycję. W przypadku gdy tego nie zrobimy system automatycznie przypisuje mu pozycję &amp;#8220;main&amp;#8221;. Gdy będziemy chcieli na jednej pozycji dodać kilka widoków, będą one &amp;#8220;sklejone&amp;#8221; w kolejności dodawania. Może się zdarzyć że mamy zdefiniowaną w szablonie pozycję, ale żaden widok nie zostanie jej przypisany. Nie jest to dużym problemem dla PHP, ale z uwagi na bardzo rygorystyczną kontrolę błędów we frameworku, otrzymamy wyjątek. Aby się on nie pokazał należy użyć wspomnianej wcześniej metody &lt;code&gt;initPosition&lt;/code&gt;. Spowoduje ona zainicjowanie pozycji na pustą wartość i dzięki temu nie otrzymamy komunikatu o błędzie. Ponieważ kolejne widoki można dodawać bezpośrednio w innym widoku, można je w sobie zagnieżdżać praktycznie do dowolnej głębokości. &lt;/p&gt;&lt;p&gt;Ponieważ wiemy już jak tworzyć widoki możemy rozwinąć naszą testową aplikację. Poprzednio stanęliśmy na definicji kontrolera. Teraz zdefiniujmy jego widok natywny. W kontrolerze zapisaliśmy, że nazywa się on show_main. Tworzymy więc plik &lt;code&gt;front/system/show/main.php&lt;/code&gt; i wypełniamy go treścią. Od razu zakładamy że szablon będzie znajdował się w pliku &lt;code&gt;front/skin/default/templates/main.tpl&lt;/code&gt; &lt;/p&gt;&lt;pre&gt;/**
 * widok natywny dla kontrolera ctrl_main
 */
class show_main extends ap_show implements iface_show {

	protected $template = 'main';

	public function init() {

	}
}

&lt;/pre&gt;&lt;p&gt;Pozostało nam wypełnić szablon &lt;code&gt;main.tpl&lt;/code&gt;. Zróbmy to np. w taki sposób: &lt;/p&gt;&lt;pre&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;
Moja pierwsza strona APEL
&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
{$main}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;&lt;p&gt;Jak widać zdefiniowaliśmy jedną pozycję o nazwie &lt;strong&gt;main&lt;/strong&gt;. Szablon nie wymaga żadnych dodatkowych danych więc funkcję &lt;code&gt;init()&lt;/code&gt; możemy pozostawić pustą. &lt;/p&gt;&lt;p&gt;W tym momencie umiemy już definiować kontrolery i widoki, co jest wystarczającą wiedzą do stworzenia strony powitalnej naszego systemu. Co trzeba więc zrobić? &lt;/p&gt;&lt;ul&gt;&lt;li&gt;po pierwsze: stworzyć widok z tekstem strony powitalnej &lt;/li&gt;&lt;li&gt;po drugie: dodać ten widok w kontrolerze &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A więc do dzieła: zaczynamy od widoku: &lt;/p&gt;&lt;pre&gt;/**
 * widok z tekstem strony powitalnej
 */
class show_welcome extends ap_show implements iface_show {

	protected $template = 'welcome';

	public function init() {

	}
}
 
&lt;/pre&gt;&lt;p&gt;Zapisujemy go w pliku &lt;code&gt;front/system/show/welcome.php&lt;/code&gt; &lt;/p&gt;&lt;p&gt;Teraz tworzymy plik &lt;code&gt;front/skin/default/templates/welcome.tpl&lt;/code&gt; i zapisujemy w nim tekst powitania. W naszym wypadku wystarczy &lt;/p&gt;&lt;pre&gt;Witam w mojej pierwszej aplikacji napisanej przy użyciu frameworka APEL
 
&lt;/pre&gt;&lt;p&gt;Teraz dodajemy widok w kontrolerze &lt;code&gt;ctrl_main&lt;/code&gt;. Robimy to w ten sposób &lt;/p&gt;&lt;pre&gt;....
public function show() {
	$show = $this-&amp;gt;addShow('show_welcome','main');
}
 
&lt;/pre&gt;&lt;p&gt;Jeśli niczego nie zepsuliśmy po wejściu na stronę główną naszego serwisu powinna ukazać się nam nasza strona powitalna.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.xp-dev.com/wiki/67486/Kontroler"&gt;&amp;lt;&amp;lt;&amp;lt; Kontroler&lt;/a&gt; - &lt;a href="http://www.xp-dev.com/wiki/67486/Baza%20danych"&gt;Baza danych &amp;gt;&amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 May 2011 10:03:48 GMT</pubDate>
      <guid>http://xp-dev.com/wiki/67486/Widok</guid>
      <dc:creator>psiwik</dc:creator>
      <dc:date>2011-05-16T10:03:48Z</dc:date>
    </item>
  </channel>
</rss>


