Witrynę wyświetlającą dużą liczbę danych możemy urozmaicić dodając menu kontekstowe. Działanie opcji menu jest zależne od tego na jakiej stronie aktualnie się znajdujemy. Realizację menu kontekstowego opiszę na przykładzie aplikacji do katalogowania płyt muzycznych.
33 i 1/3 – katalog płyt muzycznych
Menu główne
Strona główna aplikacji do katalogowania płyt muzycznych jest przedstawiona na rys. Z lewej strony widzimy menu główne, które jest identyczne na każdej podstronie serwisu. Menu zawiera opcje: Wykonawcy, Płyty, Utwory, Roczniki.
Opcje działają zawsze tak samo. Ich celem jest wyświetlenie pełnej listy rekordów danego typu. Po wybraniu opcji Wykonawcy ujrzymy pełną listę wykonawców zawartych w bazie danych, zaś opcja Roczniki wyświetla wszystkie roczniki, w jakich wydano płyty znajdujące się w bazie danych.
Menu kontekstowe
Strony prezentujące poszczególne rekordy z bazy danych zawierają – oczywiście oprócz menu głównego – menu kontekstowe. Menu kontekstowe wygląda zawsze tak samo: jest to seria ikon o wyglądzie strzałek.
Na stronie przedstawiającej dane wykonawcy opcje menu kontekstowego dotyczą wykonawcy. Zawartość strony jest przewinięta do następnego (lub poprzedniego) wykonawcy. Gdy wybranym zespołem jest Jethro Tull, to naciśnięcie strzałki Następny powoduje wyświetlenie danych Jimiego Hendriksa, zaś strzałka Poprzedni – Fleetwood Mac.
Na stronie prezentującej listę piosenek z wybranej płyty menu kontekstowe powoduje zmianę płyty danego wykonawcy. Wykonawca pozostaje niezmieniony. W ten sposób możemy przejrzeć kolejno wszystkie płyty wybranego wykonawcy. W bazie danych wprowadzono dziesięć płyt zespołu Jethro Tull. Menu kontekstowe zmienia wybraną płytę – od Aqualang (najstarsza płyta Jethro Tull zawarta w bazie) do J-Tull.com (najnowsza płyta Jethro Tull zawarta w bazie).
Menu kontekstowe dostępne na stronie wybranego roku powoduje przejście do następnego i poprzedniego rocznika. Na stronie rocznika 1971 przycisk Poprzedni przesunie nas do roku 1970, a następny – do roku 1972.
Wreszcie na stronie prezentującej wybraną piosenkę strzałki menu kontekstowego przewijają wybrany utwór, nie zmieniając wykonawcy. Umożliwia to przejrzenie tekstów wszystkich piosenek jednego wykonawcy.
Baza danych
Baza danych omawianego przykładu składa się z siedmiu tabel. Tabele: twykonawca, tplyta, tutwor, trocznik zawierają rekordy, natomiast tabele: twykonawca_has_tplyta, twykonawca_has_tutwor, tplyta_has_tutwor opisują relacje łączące rekordy poszczególnych tabel.
Po przygotowaniu modelu bazy danych w programie DBDesigner opracowujemy bazę danych. Kolejno:
- przygotowujemy skrypty .sql oraz .bat tworzące pustą bazę danych,
- przygotowujemy skrypty PHP wypełniające bazę danych rekordami na podstawie plików tekstowych,
- eksportujemy bazę danych do pliku .sql.
Skrypt PHP
Opracowując aplikację 33 i 1/3 stosujemy szablony Smarty oraz klasę PEAR::DB. Aplikacja składa się z:
- pliku głównego index.php,
- klasy dostępu do bazy danych DBA (plik dba.class.php),
- szablonów (m.in. index.tpl),
- kilku plików z funkcjami pomocniczymi (m.in. walidacja.inc.php).
Stosując klasę PEAR::DB wyniki zapytań odbieramy w postaci tablic asocjacyjnych. Efekt ten osiągniemy umieszczając w konstruktorze klasy DBA wywołanie:
$this->Fdb->setFetchMode(DB_FETCHMODE_ASSOC);
Ponadto wydając zapytania SQL zawierające dane stosujemy szablony. W miejscu danych w zapytaniu umieszczamy znak zapytania:
$q = \'
INSERT INTO
twykonawca(nazwa)
VALUES
(?)
\';
Oprócz poprzedniego szablonu zapytania SQL przygotowujemy również tablicę danych:
$t = array($AWykonawca);
Zapytanie wydajemy przekazując do metody klasy PEAR::DB zarówno szablon zapytania zawarty w zmiennej {stala}$q{/stala}, jak i dane do wypełnienia szablonu przygotowane w zmiennej {stala}$t{/stala}:
$w = $this->Fdb->query($q, $t);
Powyższe fragmenty kodu pochodzą z metody DBA_wstaw_wykonawce().
Cała metoda jest przedstawiona na listingu 1.
public function DBA_wstaw_wykonawce($AWykonawca)
{
$q = \'
INSERT INTO
twykonawca(nazwa)
VALUES
(?)
\';
$t = array($AWykonawca);
$w = $this->Fdb->query($q, $t);
if (DB::isError($w)) {
die(__LINE__ . \' \' . $w->getMessage());
} else {
return true;
}
}
W pliku głównym index.php występują cztery etapy:
- dołączenie niezbędnych bibliotek i utworzenie obiektów,
- walidacja zmiennych z tablicy {stala}$_GET{/stala},
- wybór stanu aplikacji,
- przetworzenie szablonu.
Przygotowanie aplikacji w oparciu o powyższy schemat umożliwia łatwe rozbudowywanie witryny o nowe podstrony i opcje.
Implementacja menu kontekstowego
Wykonanie menu kontekstowego przebiega w trzech krokach. Należy przygotować:
- metody klasy DBA, które ustalą niezbędne dane,
- kod PHP przekazujący informacje pobrane z bazy do szablonu,
- szablon menu kontekstowego.
Wprawdzie wszystkie menu do przewijania rekordów wyglądają identycznie (składają się z identycznych ikon), jednak z punktu widzenia programisty wygodnie jest patrzyć na nie jako na oddzielne i niezależne elementy strony. Zatem dla każdego menu przygotowujemy osobne:
- metody klasy DBA,
- kod PHP przekazujący dane do szablonu,
- szablony .tpl.
Pobieranie informacji z bazy danych
Metody pobierające dane do menu kontekstowego należy przygotować dla każdego rodzaju strony z osobna. Przewijanie: do kolejnego/poprzedniego wykonawcy należy przygotować metody:
DBA_podaj_dane_wykonawcy_prev()
DBA_podaj_dane_wykonawcy_next()
DBA_podaj_dane_wykonawcy_first()
DBA_podaj_dane_wykonawcy_last()
Strona płyt wykonawcy, przewijanie do następnej/poprzedniej płyty tego samego wykonawcy, wymaga metod:
DBA_podaj_plyte_wykonawcy_prev()
DBA_podaj_plyte_wykonawcy_next()
DBA_podaj_plyte_wykonawcy_first()
DBA_podaj_plyte_wykonawcy_last()
Do przewijania utworów wykonawcy potrzebne są metody:
DBA_podaj_utwor_wykonawcy_prev()
DBA_podaj_utwor_wykonawcy_next()
DBA_podaj_utwor_wykonawcy_first()
DBA_podaj_utwor_wykonawcy_last()
Wreszcie przewijanie roczników opracowujemy przy użyciu metod:
DBA_podaj_rocznik_prev()
DBA_podaj_rocznik_next()
DBA_podaj_rocznik_first()
DBA_podaj_rocznik_last()
Wszystkie te metody są bardzo podobne do siebie. Różnią się zapytaniem SQL. Pierwsza z nich, metoda {stala}DBA_podaj_dane_wykonawcy_prev(){/stala}, została przedstawiona na listingu 2.
public function DBA_wstaw_wykonawce($AWykonawca)
{
$q = \'
INSERT INTO
twykonawca(nazwa)
VALUES
(?)
\';
$t = array($AWykonawca);
$w = $this->Fdb->query($q, $t);
if (DB::isError($w)) {
die(__LINE__ . \' \' . $w->getMessage());
} else {
return true;
}
}
Należy zwrócić uwagę, że przewijania do następnego czy poprzedniego rekordu nie da się zrealizować poprzez zwiększanie czy zmniejszanie pojedynczej liczby. W przypadku rocznika nie możemy liczby 1971 zwiększać o jeden, gdyż nie wiemy, czy w bazie danych znajdują się jakiekolwiek płyty z roku 1972.
Przekazywanie informacji pobranych z bazy do szablonu
Przetwarzanie danych w skrypcie index.php odbywa się w dużej instrukcji switch sterowanej zmienną {stala}$akcja{/stala}. Zmienna {stala}$akcja{/stala} odpowiada za wybór odpowiedniej podstrony witryny. Kod odpowiedzialny za przekazanie odpowiednich danych do szablonu ma więc strukturę:
switch ($akcja) {
case 1:
...
break;
case 2:
...
break;
...
}
Wartość zmiennej {stala}$akcja = 7{/stala} odpowiada stronie wybranego wykonawcy. Należy wtedy – oprócz danych wykonawcy – ustalić także dane konieczne do menu kontekstowego. Dane te to informacje o następnym wykonawcy, poprzednim wykonawcy, pierwszym wykonawcy, ostatnim wykonawcy.
Należy wywołać metody:
DBA_podaj_dane_wykonawcy_prev()
DBA_podaj_dane_wykonawcy_next()
DBA_podaj_dane_wykonawcy_first()
DBA_podaj_dane_wykonawcy_last()
Po wywołaniu metod sprawdzamy czy rekord pierwszy lub ostatni nie jest równy bieżącemu. Jeśli jest, to opcje mają być nieaktywne: wstawiamy wartość false do odpowiednich zmiennych.
Wreszcie na koniec przekazujemy zmienne {stala}$prev, $next, $first, $last{/stala} do szablonu. Pełny kod odpowiedzialny za przekazanie danych do menu kontekstowego jest przedstawiony na listingu 3.
case 7:
...
$prev = $db->DBA_podaj_dane_wykonawcy_prev($wykonawca[\'nazwa\']);
$next = $db->DBA_podaj_dane_wykonawcy_next($wykonawca[\'nazwa\']);
$first = $db->DBA_podaj_dane_wykonawcy_first();
$last = $db->DBA_podaj_dane_wykonawcy_last();
if ($first[\'twykonawca_id\'] === $_GET[\'id2\']) {
$first = false;
}
if ($last[\'twykonawca_id\'] === $_GET[\'id2\']) {
$last = false;
}
$s->assign(\'prev\', $prev);
$s->assign(\'next\', $next);
$s->assign(\'first\', $first);
$s->assign(\'last\', $last);
break;
Szablon menu kontekstowego
Ostatnim etapem przygotowania menu kontekstowego jest szablon, a dokładniej: szablony. Należy ich przygotować cztery.
Każde menu kontekstowe jest zapisane w innym pliku. Mamy cztery menu kontekstowe zapisane w plikach:
- następny/poprzedni wykonawca: wykonawca-wskaznik.tpl,
- następna/poprzednia płyta wykonawcy:plyty-wykonawcy-wskaznik.tpl,
- następny/poprzedni rocznik:rocznik-wskaznik.tpl,
- następny/poprzedni utwór wykonawcy: utwory-wykonawcy-wskaznik.tpl.
Do każdego szablonu przekazujemy identycznie nazwane zmienne: {stala}$prev, $next, $first {/stala}oraz {stala}$last{/stala}
Opcje Pierwszy/poprzedni/następny/ostatni w każdym z menu mogą być nieczynne. Fakt ten stwierdzamy badając, czy odpowiednia zmienna jest logicznie prawdziwa czy nie. W szablonie instrukcja if przyjmuje postać:
{if $first}
...
{else}
...
{/if}
W przypadku gdy zmienna jest prawdziwa, drukujemy hiperłącze i ikonę o intensywnych kolorach (np. first.png). w przeciwnym wypadku pojawia się wyłącznie blada (czyli nieczynna) ikona (np. first-brak.png).
Dane do hiperłącza pobieramy ze zmiennych {stala}$prev, $next, $first{/stala} oraz {stala}$last{/stala}. Z racji na wykorzystanie trybu DB_FETCHMODE_ASSOC zmienne te są tablicami asocjacyjnymi. Do poszczególnych składowych odwołujemy się w szablonie, wykorzystując notację zbliżoną do rekordów języka Pascal oraz struktur języka C:
$first.twykonawca_id //identyfikator wykonawcy
$first.nazwa //nazwa wykonawcy
Zatem pierwsza z opcji w szablonie wykonawca-wskaznik.tpl przyjmie ostatecznie postać:
{if $first}
{else}
{/if}