Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 10.

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

Procedury wyzwalane Procedura wyzwalana (ang. trigger) - stanowi kod użytkownika przechowywany wewnątrz bazy i uruchamiany w określonych sytuacjach np.
Programowanie wizualne
SQL INJECTION Wykorzystanie błędów w językach skryptowych
K orzystanie z ogólnodostępnej wersji internetowej.
Bazy danych II Instrukcja SELECT Piotr Górczyński 25/08/2001.
PHP + MySQL część II.
Jan Aleksander Wierzbicki
Współprogramy III Ten wykład ma na celu pokazanie kolejnej ciekawej możliwości, którą oferują współprogramy. Wspólprogramy reprezentujące wyrażenia regularne.
MS Access 2003 Kwerendy Paweł Górczyński.
MS Access 2000 Kwerendy Piotr Górczyński 25/08/2001.
Bazy danych II Instrukcja INSERT Piotr Górczyński 25/08/2001.
MS Access 2000 Piotr Górczyński Dane w tabelach.
20/09/ Języki programowania 1 Piotr Górczyński Kreator form.
Kwerendy, formularze, relacje, raporty i makra
(c) 1999, Instytut Informatyki Politechniki Poznańskiej Rozdział 7: Relacje i ograniczenia integralnościowe Język definiowania danych - DDL (Data Definition.
Metody autoryzacji użytkowników wymaga integracji z systemem operacyjnym nie wymaga logowania mała pewność mechanizmu wymaga logowania duża pewność mechanizmu.
WYZWALACZE (TRIGGERY) Wyzwalacz jest specjalnym rodzajem procedury składowanej, która może być wykonana w odpowiedzi na jedną z trzech sytuacji: UPDATE.
Projektowanie warstwy serwera DisplayTag. Projektowanie warstwy serwera Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu.
Język SQL (Structured Query Language) DDL (Data Definition Language)
Przykład włamania do aplikacji internetowej poprzez modyfikację zapytań SQL Skrypty ASP Serwer bazy danych MS SQL Server Piotr Kuźniacki BDi.
SQL – Structured Query Language (3)
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 7.
Instrukcje: CREATE, INSERT, UPDATE, DELETE, DROP
Pierwsze kroki Sprzedającego w Allegro
dr hab. Ryszard Walkowiak prof. nadzw.
Użytkownicy i przywileje Sesja - przykład Błędy Komunikacja międzyskryptowa Wykład 83PD Technologie internetowe.
Tworzenie Aplikacji Internetowych
SQL - Structured Query Language
Tworzenie Aplikacji Internetowych
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 8.
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 3.
Komendy SQL do pracy z tabelami i bazami
Ms Access Formularze i raporty Marzena Nowakowska KIS, WZiMK, PŚk
PL/SQL – dalsza wędrówka
Informatyka Poczta elektroniczna.
Wykład 3 Programowanie obiektowe. Dokument HTML składa się z obiektów (standardowych i utworzonych przez użytkownika). Głównym obiektem jest document,
Wstęp - Prosta aplikacja internetowa w technologii Java EE 5 Programowanie komponentowe 1.
Windows 8.1 dostarcza spójną platformę do tworzenia aplikacji, które potrafią dostosować się do wielu urządzeń Zaprojektowane raz, działają.
Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 1.
Wydział Elektroniki Kierunek: AiR Zaawansowane metody programowania Wykład 5.
Autor: Damian Urbańczyk
Portal edukacyjny A.Ś. FORMULARZE W JĘZYKU HTML. Portal edukacyjny A.Ś. Obiekty umieszczane na stronach www Teksty Obrazy Odnośniki Tabele Ramki pływające.
Piotr Czapiewski Wydział Informatyki ZUT Wykład 2.
Opracowanie mgr Karol Adamczyk
Jak wykonać prosty licznik odwiedzin strony internetowej?
Komendy SQL do pracy z danymi
Wykład 11 Aplikacje SDI PO11-1 / 22 Single Document Interface 1.Klasy aplikacji SDI 2.Menu systemowe aplikacji SDI 3.Serializacja 4.Tworzenie widoku 5.Tworzenie.
Partnerstwo dla Przyszłości 1 Lekcja 27 Klasy i obiekty.
Wykład 2 Programowanie obiektowe. Programowanie obiektowe wymaga dobrego zrozumienia działania funkcji definiowanych przez użytkownika, w ten sposób będziemy.
EBSCOhost Collection Manager Konto osoby proponującej książki do zakupu Przewodnik support.ebsco.com.
Partnerstwo dla Przyszłości 1 Lekcja 28 Dziedziczenie i rodzaje dziedziczenia.
Współpraca PHP i MySQL Wygodniejszym i wydajniejszym sposobem przechowywania i korzystania z danych zapisanych na serwerze jest współpraca z relacyjna.
ASP.NET Kontrolki źródła danych i prezentacji danych w ASP.Net
ASP.NET Dostęp do bazy danych z poziomu kodu Elżbieta Mrówka-Matejewska.
Dominik Benduski Michał Mandecki Podstawy Visual Basic w Excelu.
Zarządzanie stanem w aplikacjach ASP.NET Elżbieta Mrówka-Matejewska
PHP (wstęp) Personal Home Page Tools (PHP Tools)
Strumienie, Wczytywanie, Zapisywanie, Operacje na plikach
Typy wyliczeniowe, kolekcje
Listy.
Widoki (views) - Perspektywy:
Realizacja aplikacji internetowych
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Wstęp - Prosta aplikacja internetowa w technologii Java EE 5
Instrukcja obsługi panelu E-gwarancji
Ms Access - formularze Marzena Nowakowska WZiMK, PŚk
Dane, zmienne, instrukcje
PGO - Projektowanie i implementacja pierwszych klas
Zapis prezentacji:

Tworzenie Aplikacji Internetowych dr Wojciech M. Gańcza 10

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)

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.

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)

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();

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); }

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

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

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); }

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);

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"]; }

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'));"); }

GroupReactor class GrupReactor { var $data; var $user; function GrupReactor(&$data, $user) { $this->data = &$data; $this->user = $user; } function processData() { //... }

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;

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

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;"); }

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

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ę

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

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

Edycja książek - widok

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(); }

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); }

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); }

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ż");

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); }

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

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. "');\">"; }

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.

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); }

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. "');\";

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; }

W następnym odcinku Reaktor aktualizujący dane dotyczące książek Zamiast edycji danych bazowych – import Książek Użytkowników Grup