Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałIzabella Wilma Został zmieniony 10 lat temu
1
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 10
2
Na początek coś prostego Na ostatnim wykładzie przygotowaliśmy 4 strony naszego programu Brakuje reaktorów – stron które będą odbierały polecenia zapisując dane do bazy Reakcja na zaznaczenie elementów jest gotowa – jest elementem strony (obiekt klasy SelectedItems)
3
Po co reaktory Jeśli strona wyświetlająca informacje będzie zajmowała się ich zapisem to: Będzie bardziej skomplikowana – zawierając dodatkowy kod Trzeba zareagować dodatkowo na sytuację – gdy dane nie przyszły Po wysłaniu danych – dziwnie zachowa się ‘refresh’ Lepiej przygotować oddzielną stronę obsługującą wysyłane dane.
4
A co z sesją? Niektóre dane trzeba zapamiętać na poziomie sesji. Dobrym miejscem są ‘cookie’ Pamiętajmy – kontrolki potrafią czytać z ‘cookie’ – nie musimy więc pisać specjalnej obsługi Reaktor czasem musi przepisać dane do ‘cookie’, by pamiętać stan aplikacji (na przykład wybraną stronę, użytkownika czy wybrane ksiązki)
5
Reaktor function react(&$dbase) { // check if any data comes through POST | GET if (count($_POST) == 0 && count($_GET)==0) { // reactor have nothis to do - just return return; } // Pass all needed information to cookies $forwarder = new ToCookieForwarder(); $forwarder->forwardToCookie("tabs"); $forwarder->forwardToCookie("logn"); $forwarder->forwardToCookie("selectedbooks"); // react on data which could come // - login $login = new LoginReactor(); $user = $login->react();
6
Reaktor… $processor = new DataReactor(&$dbase, $user); $wasProcessed = $processor->processData(); if ($wasProcessed) { $c = new Control("tabs", 0); if ($c->value == 3) { setcookie("tabs", "0", 0); } // - groups assignment edit $processor = new GrupReactor(&$dbase, $user); $processor->processData(); // reload page without POST and GET data $page = $_SERVER['PHP_SELF']; header("Refresh: 0; url=$page"); exit(0); }
7
Brakujące operacje Brakuje nam kilku klas: ToCookieForwarder – pozwalająca na przepisywanie wartości z kolekcji GET lub POST do COOKIE LoginReactor – weryfikujący dane uzytkownika DataReactor – reagujacy na edycję danych i stanu ksiązek (na razie nie potrzebny) GrupReactor – zapisujący zmiany w przydziale do grup
8
Komplikacje? Taki podział na reaktory może wydać się dziwny ale: Możemy umieścić reaktory na głównej stronie aplikacji Możemy przygotować jedną globalną stronę reaktora Jeśli ilość możliwych danych będzie większa – możemy przygotować oddzielne strony reaktorów – by odciążyć serwer A wszystko do używajac gotowych elementów
9
ToCookieForwarder class ToCookieForwarder { function forwardToCookie($name) { $x = new Control($name, ""); $v = $x->value; if (is_array($v)) { $v = implode("|", $v); } if ($v != "") { setcookie($name, $v, 0); }
10
LoginReactor class LoginReactor { function react() { $user = new Control("logn", ""); $pass = new Control("pass", ""); $lout = new Control("lout", ""); if ($lout->value != "") { $this->value = 0; setcookie("login", $this->value, 0); return 0; } if ($user->value != "" || $pass->value != "") { $data = new DataAccess(); $result = $data->getUserSecurity($user->value, $pass->value);
11
LoginReactor … if ($result->eof()) { setcookie("login", "0", 0); setcookie("loginerr", "1", 0); return 0; } else { $result= $result->get(); $user = $result[0]; setcookie("login", $user, 0); setcookie("loginerr", "0", 0); return $user; } else { return $_COOKIE["login"]; }
12
Brakująca funkcja W dostępie do bazy musimy dopisać nową funkcję: function getUserSecurity($user, $pass) { return $this->database->query(" select UsersID from Users whereUsrPassword='$pass' and ( ucase(UsrLogin)=ucase('$user') or ucase(concat(UsrFirstName,'.', UsrLastName))=ucase('$user'));"); }
13
GroupReactor class GrupReactor { var $data; var $user; function GrupReactor(&$data, $user) { $this->data = &$data; $this->user = $user; } function processData() { //... }
14
GroupReactor… $result = false; // changing grup assignment $toProcess= new SelectedItems("grup"); $belongTo = new SelectedItems("belongToGrup"); foreach ($toProcess->items as $grup) { if ($belongTo->is($grup)) { $this->data->addGrupToUser($grup, $this->user); } else { $this->data->removeGrupFromUser($grup, $this->user); } // returning information if any data were processed return $result;
15
Brakująca funkcje - db Znów brakuje funkcji dodających użytkownika do grupy i usuwających takie przypisanie. Możemy je dodać do istniejącej klasy lub utworzyć nową Jedno i drugie ma swoje zalety – na razie dodajemy do tej samej klasy. Jej podział można potem przeprowadzić bez żadnych problemów
16
Grupy – operacje na bazie function addGrupToUser($grupId, $userId) { $this->database->query(" insert into UsersGrups (UsersID, GrupsID) values($userId, $grupId);"); } function removeGrupFromUser($grupId, $userId) { $this->database->query(" delete from UsersGrups where UsersID = $userId and GrupsID = $grupId;"); }
17
Problemy… Zauważmy, że nigdzie nie sprawdzamy czy użytkownik jest już dodany do grupy lub czy istnieje przypisanie które usuwamy W pierwszym przypadku – możemy na tablicy przypisać założyć ‘contraint’ który nie pozwoli na wstawianie duplikatów i zignorować ewentualny błąd W drugim przypadku – wystarczy po prostu zignorować błąd
18
Edycja książek Edycja książek może wyglądać różnie w zależności od stanu książki Ksiązki które mamy i są potrzebne – mogą zostać zgubione – można więc usunąć je z listy posiadanych Ksiązki które mamy i nie są potrzebne – mogą zostać wystawione na sprzedaż – użytkownik może coś o nich napisać i zaproponować cenę
19
Edycja książek… Książki których nie mamy – mogą być oznaczone jako posiadane (kupione) lub użytkownik może wybrać jedną z ofert wystawionych przez innego użytkownika Ksiązki zaznaczone jako kupowane - użytkownik może zrezygnować z zakupu Sprzedający może zatwierdzić zakup – przenosząc książkę na kupującego
20
Edycja książek… Wszystkie 5 tabel zawierających elementy edycyjne można przygotować na oddzielnych stronach Można także wyświetlić je jeden pod drugim Na początek – wybieramy drugą możliwość – stronę zawsze można podzielić Wyświetlamy tylko wybrane książki
21
Edycja książek - widok
22
Panel edycji książek class BooksEditPanel { var $dbase; var $user; var $selection; var $separator; function BooksEditPanel(&$dbase, $user) { $this->dbase = &$dbase; $this->user = $user; $this->selection = new SelectedItems("selectedbooks"); $this->separator = new SectionRenderer(); }
23
renderer function render(&$output) { $this->selection->render(&$output); $len = count($this->selection->items); if (!$len) { $output->out(" Brak wybranych książek do edycji. Wybierz książki na panelu 'Wszystkie', 'Szukam' lub 'Oddam‘ zaznaczając pola wyboru i wtedy przejdź do 'Wybrane'. "); } else { $this->separator->reset(); $this->booksSelling(&$output); $this->booksBuying (&$output); $this->booksShopping(&$output); $this->booksToSell(&$output); $this->booksLost(&$output); }
24
Coś prostego - BooksSelling function booksSelling(&$output) { $transactions = $this->dbase->getTransactionsOfSeller( $this->user); $filtered = new FilterRecordset(&$transactions, 0, $this->selection, 3); if (!$filtered->eof()) { $this->separator->render(&$output, "Książki sprzedane"); $reordered = new RecordsetTransformation(&$filtered, "1+8|3|5|6|7"); $withPrice = new FormatPrice(&$reordered, "3"); $withCheck = new FormatCheckbox(&$withPrice, "4", "sold", false, true, ""); $grid = new GridBuilder("Tytuł i autor:LN2:280| Kupujący:LN2:160|Opis ksiązki:LN1| Cena:RN2:70|Potwierdzam sprzedaż:CN2: 110"); $grid->renderGrid(&$output, &$withCheck); }
25
Teraz coś … : BooksToSell function booksToSell(&$output) { // Display books the user already have but do // not need and which might be lost or may be sold $books = $this->dbase->getOwnBooks($this->user); $needs = $this->dbase->getBooksNeededByUser( $this->user); $transactions = $this->dbase-> getBooksInTransactionsOfUser($this->user); $filtered = new FilterRecordset(&$books, 0, $this->selection, 3); $notransact = new RecordsetSubtract(&$filtered, &$transactions, 0, 3); $notneeded = new RecordsetSubtract(&$notransact, &$needs, 0, 3); if (!$notneeded->eof()) { $this->separator->render(&$output, "Książki na sprzedaż");
26
BooksToSell… $toSell = $this->dbase->getUserSales($this->user); $withsales = new RecordsetJoin(&$notneeded, &$toSell, 0, 0, 3, 1); $reordered = new RecordsetTransformation( &$withsales, "3+4|0|9|10|0|0|10|0"); $withMoney = new FormatMoneyEdit(&$reordered,"3", "price", 1,"6"); $withComment = new FormatComment(&$withMoney, "2", "comment", 1, "6"); $withCheck1 = new FormatCheckbox(&$withComment, "1", "sell", "6", true, "!lost|price|comment"); $withCheck2 = new FormatCheckbox(&$withCheck1, "4", "lost", false, "!6", "!sell"); $withID = new AddHiddenIdentity(&$withCheck2, "sellId",7,0); $ready = new RecordsetTransformation(&$withID, "0|1|2|3|4"); $grid = new GridBuilder("Tytuł i autor:LN2:280| Sprzedam:CN2:110|Uwagi:LN1|Cena:RN2:70| Sprzedałem:CN2:110"); $grid->renderGrid(&$output, &$ready); }
27
Trochę logiki… FormatCheckbox(&$withComment, "1", "sell", "6", true, "!lost|price|comment"); Konstruktor klasa formatującej pola zaznaczenia zyskał dodatkowe parametry! Pozwalają na zdefiniowanie czy pole jest aktywne i jakie pola są aktywowane lub dezaktywowane podczas zaznaczania
28
Zmiany, zmiany, zmiany function format($field) { $checked = $this->testItem($this-> selected, $field); $disabled = !$this->testItem($this-> enabled, $field); $checked = ($checked) ? " checked" : ""; $disabled = ($disabled) ? " disabled" : ""; return "<input type=\"checkbox\" name=\"". $this->name. "[]\" id=\"". $this->name. $field. "\" value=\"". $field. "\"". $checked. $disabled. "onclick=\"enable(this, '". $this->action. "');\">"; }
29
TestItem Pole edycyjne może być zaznaczone Na stałe W zależności od wartości pola w rekordsecie Zależnie od obiektu pamiętającego zaznaczenia Wystarczy jedna funkcja która określi stan w zależności od danych wejściowych oraz stanu rekordu.
30
TestItem - kod function testItem(&$booler, $value) { if (is_bool($booler)) return $booler; else if (is_string($booler)) { if ('!' == substr($booler, 0, 1)) { return !($this->currentRecord[(int) (substr($booler, 1))] != ""); } else return ($this->currentRecord[(int) ($booler)] != ""); } else return $booler->is($value); }
31
Automatyczna aktywacja Niektóre kontrolki mogą być automatycznie aktywowane – na przykład pola dotyczące sprzedaży sa aktywne tylko – gdy zaznaczymy „sprzedam” Odpowiada za to dodatkowa funkcja wołana gdy element zmienia wartość "onclick=\"enable(this, '". $this->action. "');\";
32
Enable function enable(obj, other) { if (other == "" || other == null) { return; } sta = obj.checked; val = obj.value; arr = other.split("|"); for (i = 0; i < arr.length; ++i) { if (arr[i].substr(0, 1) == "!") { o = document.getElementById(arr[i].substr(1) + val); o.disabled = sta; } else { o = document.getElementById(arr[i] + val); o.disabled = !sta; }
33
W następnym odcinku Reaktor aktualizujący dane dotyczące książek Zamiast edycji danych bazowych – import Książek Użytkowników Grup
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.