W
YŻSZA
S
ZKOŁA
I
NFORMATYKI
I
Z
ARZĄDZANIA
C
OPERNICUS
WE
W
ROCŁAWIU
K
IERUNEK
:
I
NFORMATYKA
(INF)
S
PECJALNOŚĆ
: S
YSTEMY
I
SIECI
KOMPUTEROWE
(SSK)
PRACA DYPLOMOWA INŻYNIERSKA
Grzegorz ŚLIWIŃKI
PROJEKT I REALIZACJA APLIKACJI
WSPIERAJĄCEJ ZARZĄDZANIE SKLEPEM
INTERNETOWYM ZA POMOCĄ USŁUG ANALIZY
DANYCH W SQL SERVERZE
Ocena pracy
:……………....……………………………………
(ocena pracy dyplomowej, data, podpis promotora)
……………………………………………
(pieczątka uczelni)
Promotor:
dr inż. Zofia KRUCZKIEWICZ
WROCŁAW 2007
1
Spis treści
2.2 SQL Server Analysis Services
2.3 SQL Server Reporting Services
...................................................................................................
2.6.1 SQL Server Business Intelligence Development Studio
.....................................................
2.7.2 SQL Server Management Studio
........................................................................................
2.7.3 Eclipse platform – PDT Project
..........................................................................................
...................................................................................................
3. Wymagania i koncepcja projektu
3.2.4 Związki pomiędzy encjami
.................................................................................................
3.3 Rozdzielenie warstwy prezentacji od warstwy logicznej
..........................................................
4.1 Szczegółowy diagram bazy danych
...........................................................................................
4.2 Szczegółowy diagram kostki OLAP
..........................................................................................
5.2 Operacje na danych testowych, na przykładzie modułu produktów
..........................................
5.3 Generacja testowych danych zakupów
......................................................................................
6.2 Test trybów logowania użytkownika
........................................................................................
6.3 Test funkcji manipulacji danymi
...............................................................................................
6.4 Test generacji danych do analizy
..............................................................................................
2
Spis rysunków
Kostka OLAP.........................................................................................................................................7
Statystyki dostępne w systemie osCommerce [8]................................................................................10
Statystyki dostępne w Shop [9]............................................................................................................11
SQL Server Business Intelligence Development Studio - praca z wielowymiarową bazą danych.....13
SQL Server Business Intelligence Development Studio - projektowanie raportów............................13
SQL Server Management Studio.........................................................................................................14
Eclipse - PDT Project [10]...................................................................................................................15
Sybase PowerDesigner 11 Evaluation [11]..........................................................................................16
Schemat koncepcyjny systemu............................................................................................................18
Funkcje użytkownika systemu.............................................................................................................19
Diagram ERD. Ogólny obraz bazy danych..........................................................................................20
Relacje diagramu ERD........................................................................................................................21
Idea rozdzielenia warstw......................................................................................................................22
Fizyczny model bazy danych...............................................................................................................25
Diagram wielowymiarowej bazy danych OLAP.................................................................................27
Projekt interfejsu..................................................................................................................................28
Logowanie użytkownika......................................................................................................................29
Dodawanie nowego produktu..............................................................................................................30
Usuwanie klienta..................................................................................................................................31
Generacja danych do analizy...............................................................................................................32
Generacja raportu.................................................................................................................................33
Ogólny schemat działania systemu szablonów....................................................................................35
Moduł zarządzania klientami, widok standardowy.............................................................................36
Moduł zarządzania klientami: widok edycji........................................................................................36
Panel logowania...................................................................................................................................37
Operacje na produktach.......................................................................................................................38
Dimmension Usage: Połączenia pomiędzy wymiarami i miarami......................................................46
Ekran logowania systemu....................................................................................................................54
Logowanie do systemu bez opcji Zapamiętania..................................................................................54
Ekran powitalny...................................................................................................................................55
Spis ciasteczek logowania bez opcji Zapamiętaj.................................................................................55
Logowanie z opcją Zapamiętaj............................................................................................................55
Spis plików cookie z ciasteczkiem autologin......................................................................................55
Panel manipulacji danych produktów..................................................................................................56
Dodawanie nowego produktu..............................................................................................................57
Nowy produkt w bazie danych............................................................................................................57
Nowy produkt w spisie treści...............................................................................................................57
Edycja produktów................................................................................................................................57
Zmienione dane w bazie danych..........................................................................................................58
Komunikat ostrzegający przed przypadkowym usunięciem................................................................58
Komunikat o istniejacych danych transakcyjnych...............................................................................59
Krok pierwszy generacji danych transakcyjnych................................................................................59
Krok drugi generacji danych transakcyjnych......................................................................................60
Krok trzeci generacji danych transakcyjnych......................................................................................60
Komunikat o wygenerowanych danych...............................................................................................61
Wybór raportu......................................................................................................................................61
Ustawianie parametrów raportu...........................................................................................................62
Raport rocznego zestawienia sprzedaży..............................................................................................63
3
1. Wprowadzenie
Dziedzina pracy
W dzisiejszych czasach handel prowadzi się coraz częściej drogą elektroniczną. Sklepy
przeprowadzają coraz więcej transakcji bezgotówkowych – przy użyciu kart płatniczych. W
Internecie, jak grzyby po deszczu powstają sklepy internetowe: księgarnie, ze sprzętem
komputerowym, z bielizną, kosmetykami, elektroniką, a nawet spożywcze, choć te przeważnie
oferują zasięg lokalny. Projektanci takich sklepów prześcigają się w pomysłach na ergonomię i
przejrzystość interfejsu, możliwościach zapłaty za zamówienie, a także na nowe funkcje, dostępne
dla klientów.
W takim natłoku rzeczą naturalną jest silna konkurencja, a klienci są kuszeni coraz szerszym
wachlarzem promocji, coraz obszerniejszą zawartością sklepu, coraz lepszymi warunkami dostawy i
wygodniejszymi możliwościami zapłaty, bardziej ergonomicznymi i przejrzystymi interfejsami.
Oferuje im się również kolejne funkcje, poszerzające funkcjonalność sklepów.
I tu powstają pytania. Jak zwrócić uwagę klienta na „nasz” sklep? Którzy klienci są skłonni
wydać więcej pieniędzy? Którym warto zaoferować promocję? Z drugiej strony, jakie produkty
sprzedawać? Jakie warunki dostawy, zaproponować? Jakie warunki płatności? Czy podnieść cenę
towarów, ale obniżyć cenę przesyłki, czy może na odwrót, obniżyć ceny towarów, a podnieść za
przesyłkę?
Cel pracy
Odpowiedzi na te pytania może dostarczyć system, który wspomoże właściciela, bądź też
managera sklepu, poprzez analizę zgromadzonych danych. Stworzenie takiego systemu jest też
celem tej pracy. Ma to być system przyjazny, wygodny w obsłudze, odwzorowywać ogólne zasady
transakcji w Internecie. System powinien także móc współpracować z większością dostępnych na
rynku sklepów internetowych, jak również dokładnie zobrazować rzeczywistość. Jest to istotne, ze
względu na istotę decyzji podejmowanych na podstawie analizy danych.
Do realizacji tych celów opracowano, zaprojektowano i wykonano system oparty transakcyjnej
bazie danych i powiązanej z nią analitycznej bazie danych typu OLAP. Wykorzystano również
narzędzia dostarczone przez producenta sytemu bazodanowego, w celu maksymalnego uproszczenia
poszerzania możliwości systemu o nowe typy raportów, jak i modyfikacji tych już istniejących.
Zaprojektowano również przejrzysty interfejs użytkownika, oraz system generujący strony, który
pozwoli bez żadnych problemów dostosować wygląd interfejsu do konkretnego sklepu
internetowego.
W kolejnym rozdziale opisano zagadnienia teoretycznie związane z celem pracy dyplomowej.
Przedstawiono teoretyczne zagadnienia związane z bazami danych typu OLAP, których użyto do
analizy zgromadzonych danych. Przedstawiono dwie usługi dołączone do systemu baz danych MS
SQL Server 2005: Analysis Services oraz Reporting Services. Opisano również możliwości piątej
wersji języka PHP, jednego z najpopularniejszych rozwiązań, używanych w tworzeniu
dynamicznych stron WWW, w tym sklepów internetowych.
Rozdział trzeci przedstawia koncepcję systemu, jak również wymagania, które powinien
spełniać. Zaprezentowano również ideę rozdzielenia w php warstwy logicznej systemu od warstwy
prezentacji.
4
Projekt systemu przedstawiony jest w rozdziale czwartym. Zawiera on schematy obrazujące
architekturę systemu oraz idee kierujące przedsięwzięciem. Zobrazowane zostały w nim również
projekt interfejsu oraz funkcjonalność.
Rozdział piąty omawia aspekty implementacji systemu. Umieszczono w nim informację o
językach programowania użytych do stworzenia systemu.
Kolejny rozdział, szósty, zawiera testy kluczowych elementów systemu, mających
gwarantować czytelność i poprawność analizowanych danych.
W rozdziale siódmym zawarto wnioski, jakie narodziły się podczas tworzenia systemu, jak
również zawarto perspektywy rozwoju systemu.
5
2. Zagadnienia teoretyczne
W pierwszym podpunkcie zajęto się zagadnieniem OLAP (On-Line Analytical Processing).
Opisano historię baz OLAP, specyfikę oraz zalety. W dzisiejszych czasach, mimo coraz szerszego
zastosowania narzędzi typu BI (Business Intelligence), raporty często generowane są ze źródeł
transakcyjnych, co przy coraz większej ilości danych zabiera coraz więcej czasu, powodując nawet
czasowe zblokowanie bazy danych. Bardzo ważne jest, by wraz ze wzrostem ilości danych, coraz
większego ruchu w sklepie, raporty były serwowane dokładnie i szybko. W związku z tym
opracowano opis baz danych typu OLAP, porównano je z systemami transakcyjnymi, oraz innymi
rozwiązaniami stosowanymi w zarządzaniu organizacjami.
W drugim podpunkcie przedstawiono pokrótce SQL Server Analysis Services, oraz jego
głównych konkurentów. Wyjaśniono również dlaczego wybrano ten system.
Kolejny podpunkt przedstawia SQL Server Reporting Services oraz jego możliwości.
Następnie, zajęto się najnowszą, piątą, wersję języka PHP. W dzisiejszych czasach, biznes
internetowy próbuje zminimalizować wydatki, jednocześnie nie obniżając niezawodności i jakości
świadczonych usług. Poszukuje się rozwiązań tanich, powszechnych, stabilnych i łatwych w
zastosowaniu, a jednocześnie przenośnych. Takim właśnie rozwiązaniem jest PHP. Podpunkt ten
opisuje możliwości piątej wersji tego języka, a także opisuje jego zastosowania.
W piątym podpunkcie krótko przedstawiono wybrane systemy e-commerce oraz ich
możliwości z zakresu analizy i wspomagania decyzji biznesowych.
W ostatnim podpunkcie krótko opisano narzędzia służące do pracy na wybranych
technologiach.
2.1 OLAP
W roku 1993 Edward F. Codd wprowadził termin OLAP (On-Line Analytical Processing –
przetwarzanie analityczne w trybie online) i zaproponował 12 reguł opisujących bazy danych tego
typu, wzorem terminu OLTP (On-Line Transactional Processing) i 12 reguł z 1985 opisujących
transakcyjne bazy danych. I o ile jego reguły zostały odrzucone przez środowisko, to sam termin
OLAP idealnie pasował do baz danych projektowanych z myślą ułatwienia procesów decyzyjnych
w firmach [2].
Termin ten dzisiaj jest używany do opisywania narzędzi służących łatwemu udostępnianiu
zgromadzonych w hurtowni danych w postaci informacji, czyli tak potrzebnej do zarządzania
organizacjami wiedzy [2].
Zgromadzone w Hurtowni, czy też w bazie produkcyjnej dane, trudno nazwać informacją.
Jednocześnie, by móc udostępnić je w postaci informacji, muszą zostać przetworzone przez silnik
OLAP. Aby to było możliwe, dane te są pobierane przez systemy OLAP za pomocą odpowiednich
sterowników baz danych - ODBC (Open Database Connectivity).
Centralną pozycję w bazie analitycznej OLAP posiada tabela faktów. W niej to zebrane są
miary, numeryczne, agregowane wartości będące danymi analizowanymi. Do opisu danych
6
wykorzystywane są tabele wymiarów. Wszystko to razem tworzy „kostkę danych”, zwaną także
„sześcianem”. Sześcian w geometrii posiada trzy wymiary, jednak kostka danych może posiadać
równie dobrze jeden wymiar, jak i znacznie większą liczbę wymiarów, ograniczoną tylko potrzebami
użytkownika. Tak więc wyrażenie to tak naprawdę nie oddaje wyglądu „kostki OLAP”, a jej istotę.
Podobnie jak w geometrii, wielkość kostki danych oblicza się mnożąc przez siebie jej wymiary.
Rysunek 1: Kostka OLAP
Jak widać na powyższym rysunku (rys.1), OLAP prezentuje dane w postaci wielowymiarowej,
co różni się od systemów transakcyjnych, gdzie główną rolę grają pojedyncze wiersze. W systemach
OLAP analizie podlegają zbiory danych, transakcji.
Analityczne bazy danych są stosowane głowie w systemach wspomagania decyzji (DSS –
Decision Support System) do generowania przekrojowych raportów z działalności danej organizacji
według różnych kierunków analiz.. Typowe zastosowania to systemy sprzedaży, marketing, raporty
kierownictwa, budżety, prognozy pogody, raporty finansowe [1].
Jedną z zalet systemów opartych na bazach danych OLAP, jest ich szybkość. Analizy
przeprowadzone w bazie wielowymiarowej nierzadko zajmują ułamek czasu, który potrzebowałyby
na te same analizy bazy transakcyjne. W niektórych przypadkach jest to nawet 0,1% tego czasu. Jest
to możliwe dzięki agregacjom. Powstają one na bazie tabeli faktów i są wstępnie obliczane dla
różnych granulacji tychże faktów dla określonego wymiaru, a także kombinacji wszystkich
wymiarów.
Ten właśnie zabieg drastycznie skraca czas odpowiedzi. Takie podejście ma jedną wadę, baza
OLAP potrafi się dość szybko rozrosnąć, szczególnie wtedy, gdy istnieje dość dużo wymiarów. By
tego uniknąć, współczesne systemy oferują zmianę stopnia agregacji danych, a także różnorodne
metody kompresji.
7
Kostka OLAP zawiera dużą liczbę metadanych. Są to informacje o sposobie przechowywania
danych, ich strukturze, a także ich znaczeniu. Tworząc kostkę OLAP, definiując miary, mamy wpływ
również na sposób agregacji, zalecane tytuły nagłówków, a nawet formatowanie liczb, a podczas
tworzenia wymiarów, możemy zdecydować o grupowaniu niektórych atrybutów, a także, czy dana
grupa tychże atrybutów może być połączona w hierarchię. Język SQL nie jest przystosowany do
korzystania z metadanych. Bazy relacyjne, dla których został stworzony, nie zawierają ich wiele.
Dlatego też wielu dostawców technologii stworzyło własne języki zapytań. Jednak w 2001 roku
powstała rada XMLA (XML for Analysis), utworzony przez firmy Microsoft, Hyperion oraz SAS.
Zadaniem rady było opracowanie wspólnej specyfikacji pracy z bazami danych typu OLAP, a
językiem specyfikacji wybranym przez radę został MDX (MultiDimensional eXpressions) [2].
Dzięki metadanym zawartym w kostce, możliwe jest korzystanie z niej przez dowolne
narzędzie klienckie obsługujące XMLA i/lub MDX, generowanie poprawnych raportów [2].
Kolejną zaletą technologii OLAP są proste formuły, które do złudzenia przypominają te
stosowane w arkuszach kalkulacyjnych. XMLA ma jednak przewagę nad formułami z arkuszy. Raz
stworzona formuła nie musi być kopiowana i będzie działała tak samo zarówno dla dziesięciu, jak
też i tysiąca wierszy. Wprowadzając niewielką modyfikację w formule można ją wielokrotnie
używać. Kolejną zaletą są nazwy opisowe odwołań w formułach, zamiast =C2*B2, jak to ma
miejsce w arkuszach kalkulacyjnych, formuły XMLA wyglądają tak: [Cena]*[Ilosc]. Istotną zaletą
są ponownie metadane, do których próżno próbować się odwoływać w formułach arkuszy
kalkulacyjnych [2].
2.2 SQL Server Analysis Services
Decydując się na technologię OLAP można wybierać spośród kilku dostawców. Oprócz
Microsoft Corporation oferującego SQL Server Analysis Services (SSAS), są to między innymi
Hyperion Solutions Corporation z programem Essbase (na krótko nazwanego „Hyperion® System™
9 BI+™ Analytic Services™” przez wydawcę), oraz Oracle z Oracle OLAP. Essbase jest
dostarczany jako osobna aplikacja, rozwiązanie firmy Oracle Corporation jest dostępne w formie
płatnej opcji do systemu zarządzania bazą danych Oracle Database. Za to SQL Server Analysis
Services jest już zawarty w pakiecie Microsoft SQL Server 2005, podobnie jak inne narzędzia
Business Intelligence Microsoftu. Za tym ostatnim rozwiązaniem przemawia przede wszystkim
cena, która jest dużo niższa niż Essbase, jego dostępność na rynku polskim oraz prostota obsługi [2].
Dodatkowym atutem jest możliwość nawiązania połączenia z bazą danych MySQL za pomocą
sterowników MySQL dla platformy .NET dostarczanych przez sam MySQL bądź też przez
niezależną firmę CoreLab. Jest to o tyle ważne, że duża część sklepów internetowych opartych na
PHP, korzysta właśnie z bazy danych MySQL.
2.3 SQL Server Reporting Services
Przy stosowaniu technologii OLAP istotne są również raporty. SQL Server Reporting Services
(SSRS), jest właśnie narzędziem, do generacji tychże raportów. Może pracować zarówno na
relacyjnej bazie danych, jak i na bazie danych typu OLAP. Co jest bardzo istotne, Reporting Services
jest dostarczany w tym samym pakiecie, co Analysis Services. Taki sposób dystrybucji tworzy z
Reporting Services naturalne uzupełnienie możliwości wielowymiarowej bazy danych Microsoftu.
8
SSRS jest narzędziem serwerowym, znaczy to tyle, że do działania potrzebuje serwera WWW
obsługującego technologię ASP.NET. Jednym z takich serwerów jest właśnie IIS (Internet
Information Services), który jest dostępny w systemach serwerowych Microsoftu współpracujących
z SQL Server 2005, tj. Windows 2000 SP4 oraz Windows 2003. SSRS oferuje możliwość
projektowania raportów w Microsoft Visual Studio dzięki dostarczanym wtyczkom, oraz w
ograniczonym stopniu poprzez interfejs WWW. Stworzone raporty mogą być wygenerowane w
różnych formatach, między innymi PDF, XLS (Excel), CSV, XML, jak również może rozsyłać
raporty za pomocą poczty elektronicznej. Również zabezpieczenia można stosować szeroko,
zabezpieczając pojedyncze raporty, folder zawierający ich zbiór, bądź też źródło danych.
2.4 PHP 5
Historia tego niezwykłego języka zaczęła się w 1994 roku, jako zestaw narzędzi do obsługi
osobistej strony swojego twórcy Rasmusa Lerdorfa. Jego popularność wybuchła, gdy w 1998 zespół
złożony z Rasmusa oraz Andi Gutmansa Zeeva Suraskiego wydał 3 odsłonę języka. Przyczyniła się
do tego modułowość języka oraz łatwa możliwość rozszerzenia możliwości PHP za pomocą nowych
rozszerzeń. W 10 lat od pierwszej wersji, w roku 2004 została upubliczniona piąta odsłona języka
[5].
Jednym z największych usprawnień w PHP 5 jest model obiektowy. Poprzedni, wprowadzony
w 3 wersji języka i utrzymany w 4, posiadał istotne ograniczenia. Obiekty były również
przekazywane, między innymi jako parametry funkcji, tak jak inne zmienne, co powodowało ich
kopiowanie. W aktualnej wersji przekazanie obiektu jako parametru powoduje tylko przekazanie
„wskaźnika”, co jest bardziej intuicyjne. Od wersji piątej programiści mogą używać również
modyfikatorów dostępności („public”, „private”, „protected”, „static”) oraz interfejsów [7].
Kolejnym usprawnieniem jest obsługa wyjątków, jednak w samym php, ze względu na
wsteczną kompatybilność, wyjątki są wykorzystywane tylko w nowych rozszerzeniach [7].
Istotnym elementem w PHP jest Zend Engine. Zend Engine, to od 4 wersji języka, wirtualna
maszyna odpowiedzialna za uruchamianie skryptów PHP. Wersję piątą php obsługuje druga odsłona
silnika Zend Engine, która znacznie poprawia wydajność aplikacji. Zend Engine II posiada również
nowy, wydajny, moduł zarządzania pamięcią, który znacznie lepiej radzi sobie w środowiskach
wielowątkowych.
PHP 5 poprawia również bezpieczeństwo aplikacji internetowych, dzięki domyślnym
wyłączeniu zmiennych globalnych, jak również innych opcji ułatwiających pracę, jednak będących
źródłem wielu niebezpiecznych luk w aplikacjach.
PHP również może generować różne treści, nie tylko html, xml, ale również pliki obrazków w
różnych formatach, pliki PDF, arkusze kalkulacyjne xls i wiele innych. Również dzięki
wbudowanym funkcjom potrafi on nawiązać połączenie z różnymi typami serwerów, na przykład
telnet, serwery ftp, inne serwery http [5].
2.5 Istniejące systemy
Z powodu dostępności na rynku hostingowym platform obsługujących język PHP, niskich
kosztach, przy jednoczesnej ich dużej wydajności i dużych możliwościach, na rynku istnieje wiele
9
darmowych systemów e-commerce, jak np. osCommerce, Zen Cart, CRE Loaded (oparty na
osCommerce), BakeSale.
Spośród tych systemów, tylko osCommerce (rys.2) posiada moduł statystyk, jednak jego
użycie w raportach i analizach jest bardzo ograniczone, tym bardziej, że statystyki generuje na
transakcyjnej bazie danych.
Rysunek 2: Statystyki dostępne w systemie osCommerce [8]
Oczywiście, oprócz darmowych systemów istnieją również płatne, jak JShop Server (rys.3),
polska edycja Zen Cart – Zen Cart PL, czy też wiele systemów bazujących na osCommerce.
10
Rysunek 3: Statystyki dostępne w Shop [9]
Jak widać, dostępne systemy nie dają zbyt wielu możliwości generowania raportów, a
rozszerzanie funkcjonalności istniejących jest długie i czasochłonne, nie wspominając o
ograniczeniach raportowania opartego na transakcyjnej bazie danych.
11
2.6 Narzędzia
W niniejszym podpunkcie przedstawiono narzędzia związane z zagadnieniami
przedstawionymi do tej pory. Podano ich krótką charakterystykę, a także napisano, do czego służą.
Zajęto się tutaj narzędziami SQL Server Business Intelligence Development Studio i SQL Server
Management Studio firmy Microsoft, Power Designer 11 firmy Sybase oraz Eclipse – PDT Project
korporacji non-profit Eclipse Foundation.
2.6.1 SQL Server Business Intelligence Development Studio
SQL Server Business Intelligence Development Studio jest w rzeczywistości nakładką na
Visual Studio 2005, rozszerzającą jego możliwości o projektowanie i wdrażanie wielowymiarowych
baz danych typu OLAP oraz o tworzenie i publikowanie reportów SQL Server Reporting Services.
Jednak nie wymaga obecności w systemie zainstalowanej pełnej wersji Visual Studio.
Pakiet ten jest dostępny razem z SQL Server 2005 i posiada potrzebne do samodzielnego
działania składniki Visual Studio 2005. Na poniższych zrzutach ekranowych przedstawiono pracę z
wielowymiarową bazą danych (rys.4) i z raportami (rys.5).
12
Rysunek 4: SQL Server Business Intelligence Development Studio - praca z wielowymiarową bazą danych
Rysunek 5: SQL Server Business Intelligence Development Studio - projektowanie raportów
13
2.7.2 SQL Server Management Studio
SQL Server Management Studio jest aplikacją dostępną w pakiecie wraz z SQL Server 2005.
Służy ona do zarządzania serwerem bazodanowym, bazami danych oraz innymi usługami
wchodzącymi w skład pakietu SQL Server 2005. Poniżej (rys.6) przedstawiono zrzut ekranowy
aplikacji.
Rysunek 6: SQL Server Management Studio
14
2.7.3 Eclipse platform – PDT Project
Eclipse platform jest darmowym i wygodnym środowiskiem developerskim napisanym w
Javie. Dzięki wsparciu wielkich korporacji, między innymi IBM, Borland, Red Hat oraz QNX
Software Systems, a także statusie projektu jako Open Source, powstaje do niego wiele wtyczek
pozwalających na programowanie nie tylko w Javie, ale również C/C++, COBOL i php. Eclipse
platform jest również oprogramowaniem wieloplatformowym, działa między innymi na systemach
Linux, HP-UX, QNX, Solaria, Mac OS X oraz Windows. Pakietem pozwalającym na wygodne
programowanie w php jest PDT Project (PDT - PHP Development Tools) zawierający oprócz
szeregu ułatwień również debugger kodu. Około marca 2007 roku powinna się ukazać wersja 0.7
PDT Project opartego na Eclipse 3.2.2 [10].
Poniżej (rys.7) umieszczono zrzut ekranu obrazujący pracę z pakietem.
Rysunek 7: Eclipse - PDT Project [10]
15
2.7.4 Sybase PowerDesigner 11
PowerDesigner firmy Sybase jest potężną aplikacją wspomagającą projektowanie aplikacji.
Korzysta przy tym z języka UML, pozwalając na tworzenie diagramów aktywności, diagramu klas,
diagramów ERD, diagramów fizycznych baz danych. Współpracuje ona z większością systemów
bazodanowych, pozwalając między innymi na utworzenie bezpośrednio na serwerze bazodanowym
zaprojektowanej bazy danych. Wersja Evaluation, którą wykorzystano, zawiera pełną funkcjonalność
pełnej wersji i jest jedynie ograniczona czasowo. Można ją używać przez 15 dni [11].
Aplikację przedstawia poniższy (rys.8) zrzut ekranu.
Rysunek 8: Sybase PowerDesigner 11 Evaluation [11]
16
3. Wymagania i koncepcja projektu
Rozdział ten, jak podano we wstępie, zawiera wyszczególnione wymagania, jakie powinny
zostać spełnione, by system prawidłowo działał i nie sprawiał problemów w przyszłości.
Wyszczególniono cele, oraz opracowano listę zadań do wykonania.
Następnie przedstawiono diagramy, wraz z opisami, obrazujące ogólne działanie systemu, jak i
procesy, które powinny w nim zachodzić. Ma to pomóc w zrozumieniu idei przedsięwzięcia. W
czwartym rozdziale system został przedstawiony bardziej szczegółowo.
3.1 Wymagania
Przedstawiono tutaj wymagania ze strony użytkownika systemu, czyli właściciela lub
managera sklepu, jakie musi spełnić tworzony system. W wyniku analizy wymagań zidentyfikowano
funkcje systemu, jakie musi wykonać, aby spełnić postawione wymagania.
Wymagania użytkownika
1. Wygodny i ergonomiczny interfejs systemu.
2. Szybko wykonywane funkcje systemu – np. szybkie generowanie raportów
3. Całkowita wydajność systemu - generacja raportów nie powinna mieć wpływu na wydajne
działanie sklepu.
4. Przenośność systemu -możliwość dołączenia systemu do istniejącej aplikacji sklepu
internetowego.
5. Niezawodność systemu – konieczność przeprowadzenia testów systemu przed jego
wdrożeniem. Wszystkie funkcje powinny zostać poddane testom, a najważniejsze z nich
powinny zostać udokumentowane.
Zadania zaplanowane w celu opracowania koncepcji, projektu i zrealizowania systemu
spełniającego postawione wymagania
1. Zaprojektowanie relacyjnej bazy danych opartej na bazie istniejącego systemu osCommerce,
będącej źródłem danych dla kostki OLAP.
2. Zaprojektowanie kostki OLAP - wielowymiarowej bazy danych, w oparciu o usługę SQL
Server Analysis Services firmy Microsoft.
3. Opracowanie generatora danych testowych sklepu w oparciu o PHP 5, system baz danych
MS SQL.
4. Zaprojektowanie poszczególnych raportów w oparciu o usługę SQL Server Reporting
Services firmy Microsoft.
5. Przeprowadzenie wnikliwych testów opracowanego systemu, zbadanie działania i usunięcie
błędów i wad systemu.
3.2 Obraz sytemu
W tym podrozdziale przedstawiono realizację postawionych zadań. Określono również
odpowiednie, z punktu widzenia obranej technologii i kierunku badań, rozwiązania.
17
3.2.1 Model logiczny
Istotą aplikacji będzie SQL Server Analysis Services, usługa systemu bazodanowego SQL
Server 2005 firmy Microsoft, jednakże z uwagi, iż kostki OLAP służą przede wszystkim do analizy
danych, system korzysta również z bazy danych sklepu, która powinna przechowywać informacje
autoryzacyjne, logi oraz niektóre dane konfiguracyjne. Jak widać na schemacie koncepcyjnym
systemu (rys.9), SQL Server Analysis Services jest zależna od bazy danych sklepu, z której pobiera
dane, by je następnie przetworzyć w wielowymiarową bazę danych.
Z Bazy danych korzysta również sklep/generator oraz system wspomagania decyzji. Generator
korzysta z danych autoryzacyjnych, oraz zapisuje w niej wygenerowane testowe dane transakcyjne.
System wspomagania decyzji podobnie jak generator, korzysta z danych autoryzacyjnych
przechowywanych w bazie, a jednocześnie jest zależny od generatora, do którego jest podłączony
jako moduł (podobnie jak to może mieć miejsce w części administracyjnej aplikacji sklepowej).
System Wspomagania Decyzji zależny jest od SQL Server Reporting Services, który
przedstawia informacje zawarte w SQL Server Analysis Services w prostych i czytelnych dla
użytkownika raportach obrazujących procesy zachodzące w sklepie, wygenerowane generatorem.
System Wspom agania Decyzji
SQL Server Analysis Services
Baza Danych Sklepu
SQL Server Reporting Services
Sklep Internetowy/Generator
Rysunek 9: Schemat koncepcyjny systemu
3.2.2 Funkcje systemu
Przedstawiono tutaj funkcje, jakie system będzie udostępniał użytkownikom (rys.10). Przez
użytkownika rozumiemy pracownika, właściciela, lub managera, który w aplikacji sklepowej
otrzymał dostęp i uprawnienia do systemu.
Użytkownik może się zalogować do systemu i wylogować z niego. Będąc zalogowany, może
najpierw utworzyć podstawowe informacje opisowe, to jest dane kategorii, produktów, producentów
18
i klientów, które będą służyć do opisu wygenerowanych później transakcyjnych danych
przeznaczonych do analizy. Oczywiście, oprócz utworzenia danych służących do opisywania
transakcji, użytkownik ma również możliwość ich zmiany i usunięcia. Dane transakcyjne również
będą generowane przez użytkownika, który również będzie mógł je usunąć by np. wygenerować
nowe.
Wszystkie, powyżej przedstawione funkcje, ze względu na swoją naturę, wykorzystują
relacyjną bazę danych. Z wielowymiarowej bazy danych typu OLAP korzysta ostatnia funkcja,
dzięki której użytkownik może przeglądać raporty. Są one tworzone na podstawie przetworzonych
przez OLAP danych.
Użytkownik
Logowanie
Wylogowanie
Dodaj/Usuń/Edytuj kategorie produktów
Dodaj/Usuń/Edytuj producentów
Dodaj/Usuń/Edytuj klientów testowych
Wygeneruj dane testowe
Wyczyść testowe dane zakupów
Przeglądaj Raporty
Rysunek 10: Funkcje użytkownika systemu
Korzystanie z systemu uprawnień i użytkowników sklepu zapobiega dublowaniu tych
informacji, jak i konieczność podwójnej rejestracji, ponownego przyznania uprawnień. Zapobiega to
również sytuacji, gdy administrator usuwający pracownika z jednego systemu, zapomni zrobić tego
w drugim.
19
3.2.3 Model bazy danych
Poniżej przedstawiono ogólny model bazy danych, jaki wykorzystano przy projektowaniu
systemu. Jest to zmodyfikowana wersja bazy danych systemu osCommerce, jednego z bardziej
popularnych systemów służących do tworzenia sklepów internetowych. Zdecydowano się posłużyć
bazą istniejącego systemu, ze względu na charakter aplikacji, która nie powinna istnieć w oderwaniu
od sklepu, którego zarządzanie ma wspomagać. Zabieg ten pozwala wiernie odwzorować strukturę
danych sklepu, oraz umożliwia płynny i dokładny przepływ danych pomiędzy sklepem, a systemem
wspomagania decyzji.
0,n
1,n
categories
custom ers
m anufacturers
orders
orders_delivery
orders_products
products
Rysunek 11: Diagram ERD. Ogólny obraz bazy danych
Diagram ERD (związków encji), przedstawiony na rysunku 11, przedstawia model relacyjnej
bazy danych. Diagram ten pokazuje związki logiczne zachodzące pomiędzy poszczególnymi
encjami w bazie danych, a także krotność, tj ilość encji wchodzących w skład związku.
20
Jeden do jednego
Jeden do wielu
Wiele do wielu
Opcjonalne
Wymagane
Rysunek 12: Relacje diagramu ERD
Diagram zawiera siedem tabel, połączonych relacjami różnych typów, z których każda
reprezentuje obiekt rzeczywisty. Tabele te są niezbędne do działania systemu i występują w
podobnej postaci w większości systemów sklepowych. W porównaniu z oryginalną bazą systemu
osCommerce, wyodrębniono w osobnej encji adres dostawy złożonego zamówienia, który
oryginalnie był częścią złożonego zamówienia.
3.2.4 Związki pomiędzy encjami
W encji ‘customers’ przechowywane są dane klienta używane w systemie, takie jak dane
osobowe, kontaktowe, autoryzacyjne. Każdy użytkownik może złożyć wiele zamówień, dlatego też
połączono encję ‘customers’ z encją ‘orders’ relacją jeden do wielu.
Oczywiście, każdy użytkownik może chcieć, by dostarczyć zamówienie na inny adres niż
swój, nawet w kilka różnych miejsc, dlatego też encję ‘customers’ połączona relacją jeden do wielu z
encją ‘orders_delivery’.
Czymś naturalnym jest również to, że na ten sam adres dostawy, klient może złożyć wiele
zamówień. Aby to umożliwić, encję ‘orders_delivery’ z encją ‘orders’ połączono relacją jeden do
wielu.
Czym byłby jednak sklep i możliwość zamawiania, gdyby nie dostępne produkty? Właśnie w
encji ‘products’ przechowywane są informacje o produktach, cenie, ich ilości. Każdy produkt ma
oczywiście producenta, z których każdy tworzy różne produkty. Odwzorowano to wprowadzając
związek wiele do jednego z encją ‘manufacturers’.
Z drugiej strony, by katalog produktów był przejrzysty, potrzebne są kategorie, które
zgromadzą wewnątrz grupy produktów. Z tego powodu encję ‘products’ połączono relacją wiele do
jednego z encją ‘categories’.
21
Jednak nawet taki podział na kategorie może być nieczytelny, jeśli istnieje dużo kategorii. By
tego uniknąć, stworzono relację rekurencyjną wiele do jednego dla encji ‘categories’, dzięki czemu
można uzyskać w katalogu podział na kategorie główne i podkategorie.
Wprowadzono również asocjację ‘orders_products’, by uniknąć relacji wiele do wielu, jaka by
powstała w przeciwnym wypadku pomiędzy encjami ‘orders’ i ‘products’.
Encja ‘orders’, oraz asocjacja ‘orders_products’ odwzorowują razem zamówienie. Podczas,
gdy encja ‘orders’ zbiera ogólne informacje o zamówieniu, takie jak zamawiający, adres dostawy,
cena całkowita zamówienia, sposób dostawy, to asocjacja ‘orders_products’ zbiera informacje
szczegółowe o zamówionych produktach. Związek między tymi encjami to jeden do wielu, gdyż
jedno zamówienie, musi składać z wielu, a co najmniej jednej pozycji, którą reprezentuje asocjacja
‘orders_product’. Naturalnie, encja ‘orders_products’ jest połączona relacją również z encją
‘products’. Jest to relacja jeden do wielu, gdyż jeden produkt może się pojawić na wielu
zamówieniach.
3.3 Rozdzielenie warstwy prezentacji od warstwy logicznej
W php jest możliwe połączenie warstwy prezentacji z warstwą logiczną, tj. przeplatanie kodu
html, odpowiedzialnego za wygląd aplikacji z samym php, odpowiedzialnym za jej działanie. Jednak
w celu ułatwienia integracji z systemami sklepowymi, jak również przeprowadzenia ewentualnych
zmian, zdecydowano się rozdzielić obie te warstwy stosując tak zwany system szablonów. Dzięki
temu uzyskano również przejrzystość kodu źródłowego, co jest ogromną zaletą.
Warstwa Logiczna
Warstwa Prezentacji
Rysunek 13: Idea rozdzielenia warstw
22
Powyższy schemat (rys.13) przedstawia ogólną ideę systemu szablonów. Zastosowanie tego
modelu ogranicza ryzyko przypadkowego zniszczenia logiki systemu podczas zmiany wyglądu
dokumentu. Dane są wysyłane do obiektu obsługującego szablony, a ten wstawia je w odpowiednie
miejsca szablonów.
23
4. Projekt
Rozdział ten zajmuje się szczegółowo zagadnieniami przedstawionymi w poprzednich
rozdziałach. Przedstawiono tutaj fizyczny model relacyjnej bazy danych, stworzony na podstawie
diagramu ERD z poprzedniego rozdziału. Z danych zgromadzonych w tej bazie będzie generowana
zawartość wielowymiarowej bazy danych (kostki), której diagram znajduje się również w tym
rozdziale. Następnie przedstawiono projekt interfejsu systemu oraz szczegółowo opisano wszystkie
funkcje.
4.1 Szczegółowy diagram bazy danych
Przedstawiony poniżej szczegółowy diagram bazy danych został wykonany przy pomocy
programu PowerDesigner 11 firmy Sybase na licencji Evaluation. W tworzeniu diagramu posłużono
się również wykładami dr inż. Damiana Dudka. Starano się, by diagram ten dokładnie
odzwierciedlał rzeczywistość, o czym była mowa w poprzednim rozdziale.
24
categories
categories_id
cat_categories_id
parent_id
categories_nam e
int
int
int
varchar(32)
<pk>
<fk>
custom ers
custom ers_id
custom ers_gender
custom ers_firstnam e
custom ers_lastnam e
custom er_street_address
custom er_city
custom er_state
custom er_countries_nam e
int
char(1)
varchar(32)
varchar(32)
varchar(64)
varchar(32)
varchar(32)
varchar(64)
<pk>
m anufacturers
m anufacturers_id
m anufacturers_nam e
int
varchar(32)
<pk>
<ak>
orders
orders_id
delivery_id
custom ers_id
date_purchased
orders_date_finished
value
int
int
int
datetim e
datetim e
sm allm oney
<pk>
<fk1>
<fk2>
orders_delivery
delivery_id
custom ers_id
person_nam e
person_street
person_city
person_state
person_country
int
int
varchar(64)
varchar(64)
varchar(32)
varchar(32)
varchar(32)
<pk>
<fk>
orders_products
orders_id
products_id
products_nam e
products_price
final_price
products_quantity
int
int
varchar(64)
sm allm oney
sm allm oney
int
<pk,fk2>
<pk,fk1>
products
products_id
categories_id
products_nam e
products_price
m anufacturers_id
int
int
varchar(64)
sm allm oney
int
<pk>
<fk1>
<fk2>
sessions
session_id
session_value
session_start
session_tim e
varchar(32)
text
int
int
<pk>
users
user_id
user_login
user_passwd
int
varchar(40)
varchar(100)
<pk>
Rysunek 14: Fizyczny model bazy danych
W porównaniu do diagramu ERD w modelu fizycznym do bazy danych dodano dwie tabele:
‘users’ i ‘sessions’, obie na użytek autentykacji w generatorze danych. Również asocjacja stała się
osobną tabelą.
Pierwsza z nowych tabel, przechowuje id użytkownika, jego login i hasło, potrzebne do
przeprowadzenia procesu autentykacji. Druga tabela ‘sessions’, zawiera id sesji, wartość, czas
rozpoczęcia oraz czas trwania. Tabela ta przechowuje informacje pozwalające rozpoznać
użytkownika przeglądającego stronę oraz jego aktualny stan.
Tabela ‘orders_products’, która powstała na bazie asocjacji o tej samej nazwie w diagramie
ERD, zawiera złożony klucz gówny, na który składają się klucz obcy ‘orders_id’ pochodzący z
obiektu ‘orders’ oraz ‘products_id’ pochodzący z obiektu ‘products’.
4.2 Szczegółowy diagram kostki OLAP
25
Poniżej przedstawiono diagram wielowymiarowej bazy danych wykonany przy użyciu
programu Bussines Inteligence Development Studio firmy Microsoft, dostępnego w pakiecie wraz z
oprogramowaniem MS SQL Server 2005. Skorzystano również z wykładów dr inż. Pawła B.
Myszkowskiego.
Na diagramie z rysunku 15 przedstawiono wielowymiarową bazę danych typu OLAP. Oparto
ją o model płatka śniegu, dzięki czemu uzyskano przejrzyste hierarchię wymiarów.
Centrum tej bazy jest tabela faktów oparta na tabeli ‘orders_products’ z relacyjnej bazy
danych. Tabela ta zawiera wszystkie zdarzenia transakcyjne zachodzące w systemie sklepowym.
Transakcje te są również agregowane według wymiarów, pozwalając tym samym na analizę
sprzedaży w sklepie według zadanych wymiarów – kryteriów.
Tabele powstałe na podstawie pozostałych tabel bazy danych są tabelami wymiarów.
Przechowywane w nich informacje, służą do opisu danych zagregowanych w tabeli faktów. W
niektórych tabelach, informacje zostały uzupełnione o nazwane kalkulacje. W tabeli ‘customers’, są
tą to ‘plec’ oraz ‘customers_fullname’. Pierwsza zamienia symbol płci na jej nazwę, druga łączy
nazwisko i imię w tej kolejności. W tabeli ‘orders’ wszystkie nazwane kalkulacje odnoszą się do
czasu, wyodrębniając bądź to numer miesiąca (kalkulacja NumerMiesiaca), jego nazwę
(NazwaMisiac), numer kwartału, bądź semestru. Dzięki tym kalkulacjom, skonstruowany na tabeli
wymiar czasu jest czytelny i znacznie upraszcza pracę z kostką.
Pozostałe tabele wymiarów nie potrzebują takiego uproszczenia, z tego powodu nie utworzono
w nich nazwanych kalkulacji.
26
Rysunek 15: Diagram wielowymiarowej bazy danych OLAP
27
4.3 Interfejs – projekt
Interfejs, który zaprojektowano jest wygodny w obsłudze, ergonomiczny, a przede wszystkim
przejrzysty. Było to jednym z wymagań, przedstawionych w rozdziale 3.1. Obecne w nim są
funkcje, z których w danym momencie korzysta użytkownik.
Rysunek 16: Projekt interfejsu
Na rysunku 16 przedstawiono projekt okna głównego, które użytkownik zobaczy po otwarciu
systemu. Po lewej dostępne jest dla użytkownika menu, które ułatwi mu wybór pomiędzy głównymi
opcjami. Na górze znajduje się pasek ścieżki, dzięki temu użytkownik będzie zawsze wiedział, w
którym miejscu w aplikacji się znajduje. Zabieg ten ułatwia pracownikom poruszanie się po
systemie. Całość, niezależnie od wybranego modułu, posiada ten sam, ogólny wygląd, dzięki temu,
użytkownik bez problemu skorzysta z dostępnych modułów.
28
4.4 Funkcjonalność systemu
Rozdział ten opisuje szczegółowo funkcje dostępne dla użytkownika systemu, jak i części
generującej dane. Przedstawiono poniżej diagramy aktywności obrazujące poszczególne cechy
systemu.
Logowanie użytkownika
System
Baza danych aplikacji
<<Nie>>
<<Nie>>
<<T ak>>
<<Nie>>
<<T ak>>
<<Nie>>
[Aplikacja wyświetla okno logowania]
Czy użytkownik jest zalogowany?
Użytkownik wprowadza dane autoryzacyjne
Czy dane są poprawne?
[Użytkownik został autoryzowany]
Zapisanie danych do sesji
Czy użytkownik m a być pam iętany?
Utworzenie cookie
Rysunek 17: Logowanie użytkownika
Diagram z rysunku 17 przedstawia proces logowania zaimplementowany na potrzeby
generatora danych. Po otwarciu systemu w oknie przeglądarki, o ile użytkownik nie zalogował się
wcześniej i nie wybrał opcji zapamiętania – autologowania, powinien zobaczyć okno logowania.
Gdy użytkownik poda w tym miejscu swoje dane autoryzacyjne, system sprawdzi ich poprawność z
tymi, które są przechowywane w bazie danych. Jeśli będą poprawne, system dokona autoryzacji
użytkownika, a informacja o autoryzacji zostanie zawarta w sesji. Dodatkowo, jeśli użytkownik
sobie tego zażyczy, może w oknie logowania wybrać opcję autologowanie. Jeśli tak się stanie, po
zapisaniu informacji o autoryzacji do sesji, system utworzy również cookie, w którym znajdą się
dane umożliwiające ponowne, automatyczne, logowanie, gdy sesja się przeterminuje.
29
Wylogowanie polega analogicznie do procesu logowania, jedynym wyjątkiem jest brak
porównywania danych autoryzacyjnych z tymi przechowywanymi w bazie danych, a informacje z
sesji, oraz cookie są usuwane.
Dodawanie nowego produktu
System
Baza danych aplikacji
<<T ak>>
<<Nie>>
<<Nie>>
<<T ak>>
Dodaj nowy produkt
[Wyświetlenie pól do wypełnienia]
Użytkownik wypełnia pola
Czy wszystki wym agane pola zostały wypełnione?
Czy dane poprawne?
Sprawdzenie poprawności
Zapisanie inform acji
Wyświetlenie kom unikatu
Wyświetlenie kom unikatu: 2
[Dodano produkt]
Rysunek 18: Dodawanie nowego produktu
Zalogowany użytkownik może dodać produkty, używane w generatorze do wygenerowania
danych. W tym celu użytkownik powinien przejść na odpowiednią stronę – ‘Produkty’. Tam,
użytkownik powinien zobaczyć odpowiednie pola, służące do wpisania danych nowego produktu, a
także ustawienia właściwości, takich jak producent, cena, czy wybór kategorii.
30
Po wypełnieniu pól, użytkownik zapisuje informacje, a system najpierw sprawdza, czy
wszystkie wymagane pola zostały wypełnione poprawnie, a następnie, czy pola zostały wypełnione
w prawidłowy sposób. Wykrycie błędów w zawartości pól powoduje wyświetlenie odpowiedniego
komunikatu i powrót do momentu wypełniania pól. Jeśli żaden z punktów sprawdzających nie
zwróci informacji o błędzie, produkt zostanie zapisany do bazy danych, ekran wyświetli komunikat
o dodanym produkcie.
Analogicznie przebiega procedura zmiany danych produktu, jak również dodania i zmiany
danych klienta, kategorii i producenta.
Usuwanie klienta
Baza danych aplikacji
System
<<T ak>>
<<Nie>>
Usuń klienta
[Wyświetla spis klientów]
Wybór klienta do usunięcia
Czy potwierdzono usunięcie?
Usunięcie klienta z bazy
[Potwierdź usunięcie]
[Klient usunięty]
Rysunek 19: Usuwanie klienta
31
Istniejącego klienta, oprócz zmiany danych, można usunąć. Użytkownik, który chce to zrobić,
wyświetla listę klientów, i wybiera klienta, którego chce usunąć. Gdy użytkownik wciśnie
odpowiedni przycisk, system prosi go o potwierdzenie operacji, jeśli takiego potwierdzenia nie
dostanie, nastąpi powrót do spisu klientów. Natomiast po potwierdzeniu chęci usunięcia klienta,
system usunie z bazy zarówno klienta, jak i inne informacje, które są z nim związane.
Analogicznie do tego procesu przebiega usuwanie produktów, kategorii i producentów.
Generacja danych do analizy
System
Baza danych aplikacji
<<T ak>>
<<Nie>>
Generacja danych
Czy dane istnieją?
[Pierwszy krok]
Usuń dane
Określenie podstawowych wartości
[Drugi krok]
Ustaw współczynniki wzrostu
[Wyświetlenie podstawowych wartości dla m iesięcy]
Generacja
Zapisanie danych
[Dane wygenerowano]
Rysunek 20: Generacja danych do analizy
32
Mając wszystkie informacje ustawione, takie jak producenci, klienci, produkty i kategorie,
użytkownik może przystąpić do wygenerowania danych zakupów wybierając odpowiednią opcję.
Generator sprawdzi wtedy, czy dane nie zostały przypadkiem już wygenerowane, jeśli tak, wyświetli
komunikat i zapyta, czy chcemy wyczyścić bazę danych. Wyczyszczenie oznacza usunięcie
wszystkich wygenerowanych poprzednio danych transakcyjnych.
Gdy w bazie nie ma żadnych transakcji zapisanych, system proponuje użytkownikowi ich
wygenerowanie. Najpierw prosi o ustawienie ilości miesięcy, oraz ‘współczynnika zatłoczenia’, to
jest procentu iloczynu ilości klientów oraz ilości produktów. Następnie system wyświetla tabelę, w
której użytkownik może zróżnicować współczynnik wzrostu ilości transakcji, wybierając wartości
od -1 do 2, dzięki czemu zostaje wprowadzona zamierzona różnorodność danych. Po zatwierdzeniu
ustawień współczynników system wyświetla tę samą tabelę, jednak tym razem zamiast wyboru
współczynników informuje o ilości transakcji przyznanych dla każdego z miesięcy. Po naciśnięciu
przycisku ‘Generacja’, system generuje dane transakcji, a następnie zapisuje je do bazy danych. Po
wykonaniu tej czynności, wyświetla komunikat z informacjami o tym, ile transakcji zostało
wygenerowanych w sumie, jaką ilość pozycji zamówień obejmują i ile sztuk produktów.
Generacja raportu
System
SQL Server Reporting Services
SQL Server Analysis Services
Pokaż raport
Wybierz raport
[Form ularz z param etram i do wyboru]
Ustaw param etry
Przyjm ij żądanie
Pobież dane do raportu
Wygeneruj raport
[Raport wygenerowany]
Rysunek 21: Generacja raportu
Gdy transakcje zostały wygenerowane, a SQL Server Analysis Serivces dokonując ekstrakcji
danych zapisał je w kostce OLAP, możliwe jest przeglądanie raportów generowanych na podstawie
33
kostki. Użytkownik chcąc przejrzeć raporty wybiera odpowiedni z listy, następnie może wybrać
wartości dla parametrów, by zawężyć zakres danego raportu. Otrzymuje wygenerowany odnośnik
url, który otworzy mu w systemie żądany raport.
W systemie uwzględniono kilka rodzajów raportów:
−
Roczne zestawienie sprzedaży
−
Sprzedaż miesięczna wg kategorii
−
Sprzedaż roczna wg kategorii
−
Sprzedaż miesięczna według producentów
−
Sprzedaż roczna wg producentów
−
Ranking klientów
−
Sprzedaż roczna wg regionów
−
Zamówienia według regionów
4.5 System szablonów
Chociaż o samym php można powiedzieć, że jest systemem szablonów, ponieważ w kodzie
html można umieszczać zmienne php, to jednak głownie polega to na umieszczaniu w kodzie html
warstwy logicznej. Nowoczesne systemy szablonów powstają właśnie jako rozwinięcie idei
odseparowania od siebie obu tych warstw. Zamiast przeplatać kod html z kodem php umieszcza się
go w osobnych plikach, za pomocą zmiennych oznaczając miejsca, w które system szablonów
powinien wstawić zmienne. Oprócz zmiennych, podstawową konstrukcją są jeszcze tak zwane bloki,
które informują silnik systemu szablonów o miejscach kodu, które można powielać.
34
Szablon
Dane
System
szablonów
Dokument
Rysunek 22: Ogólny schemat działania systemu szablonów
Aplikacja, podczas działania, powinna informować System szablonów, z którego szablonu
chce skorzystać. Następnie wysłać wartości dla zmiennych i bloków zawartych w danym szablonie.
Aplikacja powinna również poinformować System szablonów, kiedy kończy działanie na danym
szablonie. Silnik systemu powinien wtedy skompilować szablon, i, zależnie od typu zamknięcia
szablonu, wyświetlić na ekranie lub przypisać do innej zmiennej.
Poniżej na listingu 1 przedstawiono fragment kodu szablonu index-klienci.szb, gdzie zależnie
od prowadzonych w aplikacji czynności do zmiennej {TOP_FORM} zostaje przypisany szablon
klienci-new.szb, lub klienci-edit.szb.
<
h1
>
Zarządzaj klientami
</
h1
>
<
div
>
{TOP_FORM}
</
div
>
<
h2
>
Lista klientów
</
h2
>
<
div
>
Listing 1: Fragment szablonu index-klienci.szb
35
Rysunek 23: Moduł zarządzania klientami, widok standardowy
Rysunek 24: Moduł zarządzania klientami: widok edycji
36
5. Implementacja
W rozdziale tym umieszczono kody źródłowe najważniejszych funkcji systemu. Przedstawiono
zapytania SQL kierowane do relacyjnej bazy danych oraz zapytania MDX, tworzące tabele w
Reporting Services.
5.1 Logowanie użytkownika
Panel logowania przedstawiono na rysunku 25.
Rysunek 25: Panel logowania
Kod źródłowy umieszczony na listingach w tym podrozdziale przedstawia funkcję logowania.
Pod kodem opisano szczegółowo czynności, których celem jest stworzenie algorytmu logowania i
autentykacji użytkowników.
public function
index()
{
$this
->strona->setPath(
'Login'
,
'login/'
);
//Sprawdzenie, czy użytkownik jest zalogowany
if
(
$this
->auth->clearance() )
{
$this
->tpl->setSzablon(
array
(
'main'
=>
'login-zalogowany.szb'
) );
}
else
{
$this
->tpl->setSzablon(
array
(
'main'
=>
'login-panel.szb'
) );
//Sprawdzenie, czy dane logowania zostały wysłane
if
(
isset
(
$_POST
[
'logon-send'
] ) )
{
//Próba zalogowania
if
( !
$this
->auth->login(
$_POST
[
'login'
],
$this
->hash(
$_POST
[
'passwd'
] ),
$_POST
[
'auto'
] ) )
{
$this
->tpl->setZmienna(
array
(
'LOGIN'
=>
$_POST
[
'login'
] ) );
}
else
{
//Udana próba kieruje na stronę główną
header(
'Location: '
.PATH );
}
}
}
$this
->generate();
}
Listing 2: Główna strona logowania
Fragment przedstawiony na listingu 2 tworzy główną stronę modułu logowania. Jeśli
użytkownik jest zalogowany, zostaje pobrany odpowiedni szablon z informacją o tym, jeśli nie,
zostaje pobrany szablon panelu logowania. Dane pobierane są z tablicy $_POST, przechowującej
37
żądania typu post wysłane do serwera i przekazywane do metody login obiektu auth (jej kod
przedstawiono poniżej, na listingu 3.). Udane logowanie kieruje użytkownika na główną stronę.
public function
login(
$login
,
$passwd
,
$auto
=null )
{
//zapytanie sql
$sql
=
"SELECT userID AS id FROM "
.USER.
"
WHERE userLogin='
$login
' AND userPasswd='
$passwd
';"
;
$this
->db->query(
$sql
);
//Sprawdzenie, czy zwróciło wynik
if
(
$this
->db->numrows() >
0
)
{
$row
=
$this
->db->fetch();
//Zapisanie informacji do sesji
$this
->session->setSession(
array
(
'logged'
=>
1
,
'userName'
=>
$login
,
'userid'
=>intval(
$row
[
'id'
] )
) );
//zapisanie do cookie, jeśli użytkownik sobie tego życzy
if
(
isset
(
$auto
) )
{
setcookie(
$this
->cookie,
$login
.
"||"
.
$passwd
, time()+
31104000
,
"/"
);
}
//Informacja o sukcesie
return true
;
}
else
{
//Zapisanie informacji do sesji o Anonimowym użytkowniku
$this
->session->setSession(
array
(
'logged'
=>
0
,
'userName'
=>
'Anonim'
,
'userid'
=>
0
) );
//Informacja o porażce
return false
;
}
}
Listing 3: Metoda login
Na początku tworzone jest zapytanie SQL, które od razu porównuje login i hasło użytkownika
z danymi przechowywanymi w bazie danych. Zwrot wiersza z bazy oznacza sukces, logujący się
użytkownik istnieje i podał poprawne hasło.
Następnie w sesji zapisywane są odpowiednie informacje, takie jak ID użytkownika i jego
login, które to informacje są później używane w systemie bez potrzeby odwoływania się za każdym
razem do bazy danych.
Jeśli użytkownik sobie tego zażyczył podczas wypełniania formularza logowania, w cookie
zapisywane są informacje potrzebne do jego automatycznego zalogowania (funkcja Autologowania),
gdy sesja straci ważność.
5.2 Operacje na danych testowych, na przykładzie modułu produktów
Fragment panelu zawierającego operacje na produktach przedstawiono na rysunku 26.
Rysunek 26: Operacje na produktach
38
Zaprezentowany w tym punkcie kod przedstawia operacje na produktach, jako przykład
operacji na danych testowych. Przedstawione fragmenty kodu źródłowego są odpowiednio opisane.
//Pobieranie listy produktów
$array
=
$this
->objDao->getProductsList();
if
( is_array(
$array
) )
{
foreach
(
$array
as
$key
=>
$row
)
{
//Wypełnienie kolejnych wierszy danymi producentami
$this
->tpl->setBlok(
'products_list'
,
array
(
'ID'
=>
$row
[
'id'
],
'NAME'
=>
$row
[
'name'
],
'CENA'
=>
$row
[
'price'
] ) );
//Pobranie listy kategorii
$catArray
=
$this
->objDao->getCategoriesList();
if
( is_array(
$catArray
) )
{
foreach
(
$catArray
as
$catKey
=>
$catRow
)
{
//Pobranie listy podkategorii
$subCatArray
=
$this
->objDao->getCategoriesList(
$catRow
[
'id'
] );
if
( is_array(
$subCatArray
) )
{
//Uzupełnienie szablonu listami kategorii, i podkategorii
$this
->tpl->setBlok(
'catgroup2'
,
array
(
'NAME1'
=>
$catRow
[
'name'
] ) );
foreach
(
$subCatArray
as
$subCatKey
=>
$subCatRow
)
{
$this
->tpl->setBlok(
'cat_list2'
,
array
(
'NAME1'
=>substr(
$catRow
[
'name'
],
0
,
5
),
'NAME2'
=>
$subCatRow
[
'name'
],
'ID2'
=>
$subCatRow
[
'id'
],
'CAT_SELECT'
=>(
$row
[
'catid'
] ==
$subCatRow
[
'id'
] ) ?
' selected="selected" '
:
''
) )
;
}
}
}
}
//Pobranie listy producentów
$manArray
=
$this
->objDao->getProducerList();
if
( is_array(
$manArray
) )
{
foreach
(
$manArray
as
$manKey
=>
$manRow
)
{
//uzupełnienie szablonu o listę producentów
$this
->tpl->setBlok(
'producer_list2'
,
array
(
'MAN_NAME'
=>
$manRow
[
'name'
],
'MAN_ID'
=>
$manRow
[
'id'
],
'MAN_SELECT'
=>(
$row
[
'manid'
] ==
$manRow
[
'id'
] ) ?
' selected="selected" '
:
''
) );
}
}
}
}
Listing 4: Wyświetlanie listy producentów
Przedstawiony na listingu 4 fragment kodu odpowiada za tworzenie listy produktów wraz z
opcjami służącymi do działania na nich. Za pomocą pętli foreach, każdy z produktów otrzymuje listę
kategorii z domyślnie zaznaczoną tą, w której dany produkt się znajduje tak samo rozwiązana jest
lista producentów, gdzie każdy produkt otrzymuje listę z domyślnie wybranym producentem
przypisanym do danego produktu.
Formularz odpowiedzialny za dodawanie nowego produktu nie otrzymuje domyślnych
wyborów w tych listach.
39
if
(
isset
(
$_POST
[
'save'
] ) )
{
$this
->objDao->saveProduct(
$_POST
[
'produkt'
],
$_POST
[
'cat'
],
$_POST
[
'producent'
],
$_POST
[
'price'
] );
}
elseif
(
isset
(
$_POST
[
'edit'
] ) )
{
$this
->objDao->editProduct(
$_POST
[
'id'
],
$_POST
[
'produkt'
],
$_POST
[
'price'
],
$_POST
[
'cat'
],
$_POST
[
'producent'
] );
}
elseif
(
isset
(
$_POST
[
'del'
] ) )
{
$this
->objDao->delProduct(
$_POST
[
'id'
] );
}
Listing 5: Wybór procedur sterowania danymi
Kod przedstawiony na listingu 5 odpowiada za wywoływanie odpowiednich procedur
sterowania danymi. Zależnie od przyciśniętego przycisku przesyła dane do odpowiedniej metody
obiektu operującej na danych dla tego modułu. Informacja o przyciśniętych przyciskach jest
przekazywana w tablicy $_POST, gdzie nazwa elementu jest nazwą przycisku.
//Zapisywanie produktu do bazy danych
public function
saveProduct(
$name
,
$cat
,
$prod
,
$price
)
{
if
( !
empty
(
$name
) && !
empty
(
$price
) && !
empty
(
$cat
) && !
empty
(
$prod
) )
{
$sql
=
"INSERT INTO "
.PROD.
"
(products_name, categories_id, manufacturers_id, products_price)
VALUES('
$name
','
$cat
','
$prod
','
$price
');"
;
$this
->db->query(
$sql
);
return true
;
}
else
{
return false
;
}
}
Listing 6: Metoda saveProduct
Kod przedstawiony tutaj (listing 6), to metoda dodająca produkt do bazy danych. Najpierw
sprawdzane są przekazane zmienne, czy przypadkiem nie są puste. Jeśli do metody nie przekazano
pustych danych, zostaje stworzone zapytanie SQL, a następnie wykonane.
public function
editProduct(
$id
,
$name
,
$price
,
$catid
,
$manid
)
{
if
( !
empty
(
$id
) && !
empty
(
$name
) && !
empty
(
$price
) && !
empty
(
$catid
) && !
empty
(
$manid
) )
{
$sql
=
"UPDATE "
.PROD.
"
SET products_name='
$name
', products_price='
$price
', categories_id='
$catid
', manufacturers_id='
$manid
'
WHERE products_id='
$id
';"
;
$this
->db->query(
$sql
);
return true
;
}
else
{
return false
;
}
}
Listing 7: Metoda editProduct
Metoda przedstawiona na listingu 7 odpowiada za edycję danych produktu. Podobnie, jak przy
dodawaniu, po sprawdzeniu danych, tworzone jest zapytanie, które zostaje następnie wykonane.
Podobnie do obu powyższych metod wygląda metoda odpowiedzialna za usuwanie produktu z bazy
danych. Różnicą jest tylko zapytanie, oraz fakt, że metoda wymaga tylko podania id. Zapytanie to
przedstawiono na listingu 8.
40
$sql
=
"DELETE FROM "
.PROD.
"
WHERE products_id='
$id
';"
;
Listing 8: Zapytanie SQL usuwające produkt z bazy danych.
5.3 Generacja testowych danych zakupów
Analiza musi opierać się na danych. Dane poddane analizie w niniejszym systemie są
generowane sztucznie tak, by symulować miesięczne natężenie ruchu - zakupów, jego wzrosty i
spadki, w sklepie internetowym. Oczywiście, użytkownik powinien sam ustalić w których
miesiącach ruch powinien wzrastać, a w których maleć, jednak aby dane nie wyglądały zbyt
sztucznie, zastosowano pewien stopień losowości, dlatego też ustawienie współczynnika wzrostu na
1, wcale nie musi oznaczać wzrostu ilości transakcji o 10% w stosunku do średniej ilości transakcji z
poprzednich miesięcy, tylko mniej. W ten sposób można wygenerować na przykład zwiększony ruch
w okresie świąt Bożego Narodzenia, w okresie komunii, zakończenia i rozpoczęcia roku szkolnego.
Poniższy kod źródłowy zawiera funkcje i metody, które generują zestaw danych testowych.
public function
index()
{
$this
->tpl->setSzablon(
array
(
'main'
=>
'index-generator.szb'
) );
if
(
isset
(
$_POST
[
'step2'
] ) )
{
$this
->strona->setPath(
'Krok 2'
,
'generator/'
);
$this
->step2();
}
elseif
(
isset
(
$_POST
[
'step3'
] ) )
{
$this
->strona->setPath(
'Krok 3'
,
'generator/'
);
$this
->step3();
}
elseif
(
isset
(
$_POST
[
'generate'
] ) )
{
$this
->strona->setpath(
'Generacja'
,
'generator/'
);
$this
->step4();
}
elseif
(
isset
(
$_POST
[
'clean'
] ) )
{
$this
->objDao->cleanOrders();
header(
'Location: ./'
);
}
else
{
$this
->strona->setPath(
'Krok 1'
,
'generator/'
);
if
(
$this
->objDao->ordersExists() )
{
$this
->tpl->setSzablon(
array
(
'step'
=>
'generator-pelne.szb'
) );
}
else
{
$this
->tpl->setSzablon(
array
(
'step'
=>
'generator-pierwszy.szb'
) );
}
$this
->tpl->closeSzablon(
'STEPS'
);
}
$this
->generate();
}
Listing 9: Główna strona generacji danych
Metoda przedstawiona na listingu 9 steruje wyborem etapu generacji poprzez przyciskane
przez użytkownika przyciski (tablica $_POST, gdzie odpowiednie elementy odpowiadają
przyciskom). Dodatkowo wyświetla pierwszy ekran, którego funkcjonalność zależy od tego, czy
41
dane są już wygenerowane, czy nie. Jeśli są, zostaje wyświetlony szablon ‘generator-pelne.szb’,
zawierający informację o tym, ze baza jest pełna, oraz możliwość wykasowania zawartości bazy
(przycisk ‘clean’). Wtedy też, jak również w przypadku, gdy baza od początku nie zawiera danych,
zostaje wyświetlony szablon ‘generator-pierwszy.szb’, zawierający ekran pierwszego kroku
generacji, na którym użytkownik określa liczbę miesięcy, dla których zostaną wygenerowane dane
(liczone do miesiąca obecnego), oraz Współczynnik Zatłoczenia, będący procentem z iloczynu
produktów i klientów.
$customers
=
$this
->objDao->getClientsNumber()
$products
=
$this
->objDao->getProductsNumber()
$transactions
= ceil(
$customers
[
'quant'
] *
$products
[
'quant'
] *
$_POST
[
'wt'
] /
100
)
Listing 10: Ustalanie ilości transakcji
Na początek (listing 10) określana jest ilość produktów i klientów, a następnie wyznaczana
ilość transakcji. Ilość ta odnosi się tylko do pierwszego miesiąca, dla których dane mają zostać
wygenerowane, w kolejnych miesiącach, ilość ta będzie rosła, lub malała, częściowo zależna od
współczynników wzrostu ustawianych dla każdego z miesięcy.
$year
=date(
'Y'
) - floor(
$_POST
[
'month'
] /
12
);
$month
= date(
'm'
) - (
$_POST
[
'month'
] %
12
);
if
(
$month
<=
0
)
{
$year
--;
$month
+=
12
;
}
$startTime
= strtotime(
$year
.
'-'
.
$month
.
'-01'
);
Listing 11: Określenie daty początkowej
Następnie (listing 11) określana jest data początkowa, od której generowana będzie zawartość
bazy danych. Z formularza kroku pierwszego generacji, pobierana jest wybrana ilość miesięcy.
Służy ona do wyliczenia daty początkowej, która następnie zamieniana jest do unikowego znacznika
czasu, naturalnej postaci daty w języku php.
42
$yearGen
=
$year
;
$monthGen
=
$month
;
for
(
$i
=
0
;
$i
<=
$_POST
[
'month'
];
$i
++ )
{
(
$i
>
0
) ?
$monthGen
++ :
$monthGen
;
if
(
$monthGen
>
12
)
{
$yearGen
++;
$monthGen
-=
12
;
}
if
(
$yearBlok
!=
$yearGen
)
{
$this
->tpl->setBlok(
'rok'
,
array
(
'ROK'
=>
$yearGen
) );
$yearBlok
=
$yearGen
;
}
$this
->tpl->setBlok(
'months'
,
array
( ) );
if
(
$i
==
0
)
{
for
(
$j
=
1
;
$j
<
$month
;
$this
->tpl->setBlok(
'not_month'
,
array
( ) ),
$j
++ );
}
$this
->tpl->setBlok(
'month'
,
array
(
'ID'
=>
$i
) );
}
$this
->tpl->setBlok(
'months'
,
array
( ) );
for
(
$j
=
12
;
$j
>
$monthGen
;
$this
->tpl->setBlok(
'not_month'
,
array
( ) ),
$j
-- );
$this
->tpl->closeSzablon(
'STEPS'
);
Listing 12: Przygotowanie siatki miesięcy i lat
Ostatnim etapem kroku drugiego, jest przygotowanie ekranu, na którym użytkownik będzie
mógł ustawić ‘współczynnik wzrostu’ dla konkretnych miesięcy (listing 12). Kolejne elementy są
ułożone na siatce miesięcy i lat, aktywowana dla nich zawartość szablonu, zawierająca pole wyboru
współczynnika znajduje się w bloku ‘month’, natomiast ‘not_month’ służy do aktywowania pustego
pola, pomagającego nadać siatce estetyczny wygląd. Przykładowo, jeśli generacja ma nastąpić od
miesiąca marca, przed polem wyboru współczynnika wzrostu dla marca, zostaną wstawione dwa
puste pola.
Krok trzeci określa ostateczną ilość transakcji w danym miesiącu.
$yearGen
= date(
'Y'
,
$_POST
[
'startDate'
])
$monthGen
= date(
'm'
,
$_POST
[
'startDate'
])
Listing 13: Określenie pierwszego miesiąca i roku
Najpierw (listing 13) pobierany jest uniksowy znacznik czasu, określający datę pierwszego
miesiąca.
Następnie, w pętli foreach, obejmującej kod z listingów 14 i 15, dla każdego miesiąca
obliczana jest ilość transakcji, zmieniająca się pod wpływem współczynnika transakcji i wartości
losowej. W pętli tej znajdują się również instrukcje pilnujące poprawności numerycznej zmiennych
określających rok i miesiąc.
$time
= strtotime(
$yearGen
.
'-'
.
$monthGen
.
'-'
.date(
't'
, strtotime(
$yearGen
.
'-'
.
$monthGen
.
'-01'
) ) ) +
86400
;
Listing 14: Obliczenie uniksowego znacznika czasu dla pierwszego dnia następnego miesiąca
Dla każdego miesiąca określane są najpierw ramy czasowe, czyli znacznik czasowy
pierwszego dnia danego miesiąca i znacznik pierwszego dnia następnego miesiąca, przy czym
43
przekazywany dalej jest tylko ten ostatni. System dalej korzysta ze znacznika końcowego
poprzedniego miesiąca, lub ze znacznika określającego pierwszy miesiąc, który jest przesyłany
osobno. Parametr ‘t’ funkcji date, określa ilość dni danego miesiąca, która to ilość służy potem jako
numer ostatniego dnia miesiąca. Dodając do tak wygenerowanego znacznika daty 86400,
otrzymujemy znacznik daty dla pierwszego dnia następnego miesiąca. Liczba ta, to długość dnia w
sekundach.
if
(
$monthGen
== date(
'm'
,
$_POST
[
'startDate'
] ) &&
$yearGen
== date(
'Y'
,
$_POST
[
'startDate'
] ) )
{
for
(
$j
=
1
;
$j
<
$monthGen
;
$this
->tpl->setBlok(
'not_month'
,
array
() ),
$j
++ );
$this
->tpl->setBlok(
'month'
,
array
(
'TRANS'
=>
$trans
,
'TIME'
=>
$time
) );
}
else
{
$tendence
= ( rand(
79
,
121
) /
100
) + (
$wx
/
10
);
$monthsTrans
= ceil( (
$trans
/
$i
) *
$tendence
);
$this
->tpl->setBlok(
'month'
,
array
(
'TRANS'
=>
$monthsTrans
,
'TIME'
=>
$time
) );
$trans
+=
$monthsTrans
;
}
Listing 15: Obliczanie ilości transakcji dla danego miesiąca
Dla pierwszego miesiąca ilość transakcji została określona ręcznie w poprzednich krokach.
Dlatego też tutaj zostaje przekazana bez zmian. Natomiast ilość dla pozostałych miesięcy jest już
zmieniana częściowo pod wpływem współczynnika wzrostu ustawianego dla każdego miesiąca w
kroku czwartym, a częściowo losowo, również średnia arytmetyczna transakcji z poprzednich
miesięcy wpływa na ilość transakcji w danym miesiącu.
Krok czwarty generacji, to już właściwa generacja.
$startDate
=
$_POST
[
'startDate'
]
$clients
=
$this
->objDao->getClientsID()
$products
=
$this
->objDao->getProductsList()
$quantClients
= count(
$clients
)
$quantProducts
= count(
$products
)
Listing 16: Przygotowanie danych do generacji
Najpierw zostają pobrane danych, tak jak powyżej. Data początkowa jest przesyłana z
poprzedniego ekranu, z kroku trzeciego. Natomiast z bazy danych pobierana jest lista klientów do
tablicy clients i produktów do tablicy products. Ponieważ na tej ostatniej będą dokonywane operacje
przy okazji każdej transakcji będzie tworzona kopia tej tablicy o nazwie tmpProducts.
Po tym, w pętli foreach, dla każdego z miesięcy zostają wygenerowane transakcje.
$endDate
=
$_POST
[
'time'
][
$key
]
Listing 17: Pobranie unikowego znacznika czasu dla pierwszego dnia następnego miesiąca.
Najpierw zostaje pobrany znacznik czasu. Jak napisano powyżej, znacznik ten zamyka
przedział czasowy dla danego miesiąca. Otwiera go znacznik pobrany dla poprzedniego miesiąca,
lub początkowy, jeśli jest to pierwszy miesiąc, dla którego zostają wygenerowane transakcje, w
ilości określonej w poprzednim kroku.
$shoppingDate
= rand(
$startDate
,
$endDate
)
$monthsTransactions
[
$key
][
$shoppingDate
][
'client'
] =
$clients
[rand(
0
, (
$quantClients
-
1
) )]
Listing 18: Określenie dnia i godziny transakcji zawartej w danym miesiącu.
Najpierw z przedziału czasowego zostaje wylosowany znacznik czasu dla danej transakcji.
44
$transactionW
= rand(
0
,
100
)
Listing 19: Określenie ilości różnych produktów
Następnie zostaje określona ilość różnych produktów, elementów zamówienia, w danym
zamówieniu. Wylosowana liczba powyżej 90 oznacza trzy różne produkty, pomiędzy 90 a 60 dwa, a
w pozostałych przypadkach 1. W taki sam sposób określana jest ilość danego produktu w.
$tmpProductID
= rand(
0
, (
$quantProducts
- (
1
+
$i2
) ) );
$monthsTransactions
[
$key
][
$shoppingDate
][
'trans'
][
$i2
][
'productsNumber'
] =
$productQuant
;
$monthsTransactions
[
$key
][
$shoppingDate
][
'trans'
][
$i2
][
'product'
] =
$tmpProducts
[
$tmpProductID
];
$monthsTransactions
[
$key
][
$shoppingDate
][
'value'
] += (
$productQuant
*
$
monthsTransactions
[
$key
][
$shoppingDate
][
'trans'
][
$i2
][
'product'
][
'price'
] );
Listing 20: Określanie zamawianych pozycji
Dla każdego elementu zamówienia, określony jest konkretny produkt, obliczana jest również
cena danej ilości danego produktu.
$lastElement
= array_pop(
$tmpProducts
);
f
(
$monthsTransactions
[
$key
][
$shoppingDate
][
'trans'
][
$i2
][
'product'
][
'id'
] !=
$lastElement
[
'id'
] )
{
$tmpProducts
[
$tmpProductID
] =
$lastElement
;
}
Listing 21: Eliminacja wybranych już do danego zamówienia produktów
Fragment z listingu 21 ma za zadanie wyeliminować z tymczasowej tablicy produktów ten,
który został już w danej transakcji wykorzystany. Jeśli transakcja obejmuje więcej niż jedną pozycję,
kolejne produkty będą wybierane z pomniejszonej już puli.
ksort(
$monthsTransactions
[
$key
] );
$startDate
=
$endDate
;
Listing 22: Sortowanie tablicy transakcji
Po wygenerowaniu danych da danego miesiąca, tablica transakcji zostaje posortowana rosnąco
według znacznika czasu. Dzięki temu dane zapisane do bazy danych są czytelniejsze.
foreach
(
$monthsTransactions
as
$key
=>
$month
)
{
foreach
(
$month
as
$shoppingDate
=>
$shoppingContent
)
{
$transactionsQuantity
++;
$id
=
$this
->objDao->addOrder(
$shoppingDate
,
$shoppingContent
[
'client'
],
$shoppingContent
[
'value'
] );
foreach
(
$shoppingContent
[
'trans'
]
as
$orderDetail
)
{
$transDetQuantity
++;
$prodDetQuant
+=
$orderDetail
[
'productsNumber'
];
$this
->objDao->addOrderDetail(
$id
,
$orderDetail
[
'product'
],
$orderDetail
[
'productsNumber'
] );
}
}
}
Listing 23: Zapisywanie transakcji do bazy danych
Na koniec w złożonej pętli foreach, transakcje są zapisywane do bazy danych poprzez
odpowiednie metody obiektu objDao. Dodanie nowego zamówienia zwraca id, które potrzebne jest
przy dodaniu pozycji tego zamówienia.
45
public function
addOrder(
$date
,
array
$customer
,
$value
)
{
$date
= date(
"Y-m-d H:i:s"
,
$date
);
$did
=
$this
->getDeliveryID(
$customer
[
'id'
] );
$sql
=
"INSERT INTO "
.ORDER.
"
(date_purchased, customers_id, value, delivery_id)
VALUES('
$date
','"
.
$customer
[
'id'
].
"','
$value
','
$did
');"
;
$this
->db->query(
$sql
);
return
$this
->db->lastid();
}
Listing 24: Metoda addOrder
Przed dodaniem zamówienia do bazy danych, uniskowy znacznik czasu jest konwertowany na
datę o takim formacie, jaki jest przechowywany przez pole DateTime bazy danych MS SQL. Dzięki
temu datę tę można wykorzystać bez problemów w SQL Server Analysis Services. Następnie
tworzone jest zapytanie SQL wstawiające dane do bazy.
public function
addOrderDetail(
$orderId
,
array
$product
,
$quantity
)
{
$sql
=
"INSERT INTO "
.ORD_DET.
"
(orders_id, products_id, products_name, products_price, final_price, products_quantity )
VALUES('
$orderId
','"
.
$product
[
'id'
].
"','"
.
$product
[
'name'
].
"','"
.
$product
[
'price'
].
"','
"
.(
$product
[
'price'
] *
$quantity
).
"','
$quantity
');"
;
$this
->db->query(
$sql
);
}
Listing 25: Metoda addOrderDetail
Podobnie do metody dodającej transakcje, wygląda metoda addOrderDetail (listing 25)
dodająca kolejne pozycje transakcji do bazy danych. Dane są przekazywane w parametrach,
następnie tworzone jest zapytanie SQL, którego wykonanie dodaje dane do bazy danych.
5.4 Konstrukcja kostki OLAP
Do stworzenia kostki OLAP użyto narzędzia SQL Server Bussiness Inteligence Development
Studio, firmy Microsoft. Diagram tabeli faktów i tabel wymiarów zaprezentowano w rozdziale 4.2
podając jednocześnie, co będzie zanalizowane.
Rysunek 27: Dimmension Usage: Połączenia pomiędzy wymiarami i miarami
Na rysunku 27 zaprezentowano siatkę grup miar (Measure Groups) i Wymiarów
(Dimmensions). W polach, na przecięciu się kolumn (miar) i wierszy (wymiarów), jest informacja,
w jaki sposób dany wymiar łączy się z daną grupą miar. Dla połączeń bezpośrednich, znajduje się
tam nazwa kolumny tabeli, dla połączeń pośrednich, znajduje się nazwa tabeli pośredniczącej.
Dzięki temu, można mieć pewność, ze miary będą zagregowane według wymiarów w odpowiedni
46
sposób, co umożliwi poprawną ich analizę. Poszczególne grupy miar to Fakty sprzedaży,
zawierająca miary wartości sprzedaży oraz ilości sprzedanych produktów, Ilość zamówień
zawierająca ze względu na jej charakter wyliczeniowy tylko ilość zamówień oraz Ilość produktów
zawierająca podobnie jak Ilość zamówień, tylko miarę określającą ilość różnych produktów.
W bazie danych OLAP zastosowano również szereg nazwanych kalkulacji, które poprawiają
czytelność analizowanych danych.
CASE
WHEN DATEPART(month, date_purchased) = 1 THEN 'Styczeń'
WHEN DATEPART(month, date_purchased) = 2 THEN 'Luty'
WHEN DATEPART(month, date_purchased) = 3 THEN 'Marzec'
WHEN DATEPART(month, date_purchased) = 4 THEN 'Kwiecień'
WHEN DATEPART(month, date_purchased) = 5 THEN 'Maj'
WHEN DATEPART(month, date_purchased) = 6 THEN 'Czerwiec'
WHEN DATEPART(month, date_purchased) = 7 THEN 'Lipiec'
WHEN DATEPART(month, date_purchased) = 8 THEN 'Sierpień'
WHEN DATEPART(month, date_purchased) = 9 THEN 'Wrzesień'
WHEN DATEPART(month, date_purchased) = 10 THEN 'Październik'
WHEN DATEPART(month, date_purchased) = 11 THEN 'Listopad'
WHEN DATEPART(month, date_purchased) = 12 THEN 'Grudzień'
ELSE 'Nieznany'
END
Listing 26: Nazwana kalkulacja NazwaMiesiac
Kod z listingu 26, to nazwana kalkulacja ‘NazwaMiesiac’. Zależnie od miesiąca przyjmuje
odpowiednią dla niego nazwę. W kostce tej znajdują się również inne kalkulacje, jednak ze względu
na to, że większość operuje na dacie, zostały one pominięte w tym rozdziale.
5.5 Raporty
SQL Server Reporting Services operuje na plikach .rdl, zbudowanych za pomocą języka xml.
Jednak do projektowania służy podobnie, jak przy wielowymiarowej bazie danych typu OLAP, SQL
Server Business Inteligence Development Studio.
SELECT
NON
EMPTY
{ [Measures].[Wartość sprzedaży], [Measures].[Ilość zamówień] }
ON
COLUMNS
,
NON
EMPTY
{ ([Zamówienia].[Rok kalendarzowy].[Miesiac].
ALLMEMBERS
) }
DIMENSION
PROPERTIES
MEMBER_CAPTION
,
MEMBER_UNIQUE_NAME
ON
ROWS
FROM
[Artificial Shop]
CELL
PROPERTIES
VALUE
,
BACK_COLOR
,
FORE_COLOR
,
FORMATTED_VALUE
,
FORMAT_STRING
,
FONT_NAME
,
FONT_SIZE
,
FONT_FLAGS
Listing 27: zapytanie MDX określające dataset raportu czas-sprzedaz.rdl
Zapytanie MDX z listingu 27 pobiera z bazy danych OLAP informacje o „Wartości sprzedaży”
i „Ilości zamówień”, dla hierarchii „Rok kalendarzowy” wymiaru „Zamówienia” do DataSetu
danego raportu. Zapytanie to pochodzi z raportu „czas-sprzedaz.rdl”.
47
<ReportParameters>
<ReportParameter Name="rok">
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>All</Value>
</Values>
</DefaultValue>
<AllowBlank>true</AllowBlank>
<Prompt>rok</Prompt>
</ReportParameter>
</ReportParameters>
Listing 28: Definicja parametru raportu
Powyższy fragment kodu xml, definiuje parametr raportu. Typ parametru to String, a domyślna
wartość „All”.
<Filters>
<Filter>
<Operator>Equal</Operator>
<FilterValues>
<FilterValue>
=iif(Parameters!rok.Value="All",Fields!Rok.Value,Parameters!rok.Value)
</FilterValue>
</FilterValues>
<FilterExpression>=Fields!Rok.Value</FilterExpression>
</Filter>
</Filters>
Listing 29: Definicja filtrów datasetu
Ten fragment odpowiada za filtrację danych w DataSecie ze względu na wartość parametru.
Jeśli parametr „rok” ma wartość „All”, co jest jego wartością domyślną, pole „Rok” przyjmuje
wartość standardową, natomiast, jeśli parametr ten przyjmie inną wartość, zostanie ona przypisana
polu „Rok”, ograniczając w ten sposób raport tylko dodanego roku.
48
5.6 System szablonów
Jednym z istotniejszych, ze względu na wykonanie aplikacji, elementów systemu jest system
szablonów. System ten, operując na szablonach elementów stron zapisanych w pliku tekstowym,
otrzymuje z aplikacji informację co i w jaki sposób w szablonie umieścić, oddzielając tym samym
warstwę logiczną od warstwy prezentacji.
$this
->tpl = Template::getInstance();
Listing 30: Utworzenie obiektu systemu szablonów.
By można było korzystać w danym module aplikacji z systemu szablonów, najpierw trzeba
utworzyć odpowiedni obiekt, tak jak na listingu 30.
public static function
getInstance(
$tpl
=
""
)
{
if
(
self
::
$instance
==
false
)
{
self
::
$instance
=
new
Template(
$tpl
);
}
return self
::
$instance
;
}
Listing 31: Metoda getInstance
Dzięki metodzie getInstance przedstawionej na listingu 31, na jednym szablonie można
jednocześnie pracować w różnych miejscach systemu. Metoda zwraca referencję do już istniejącego
obiektu, a jeśli taki nie istnieje, tworzy go.
$this
->tpl->setSzablon(
array
(
'main'
=>
'index-generator.szb'
) );
Listing 32: Definicja szablonu
Posiadając utworzony obiekt szablonu, definiuje się szablon, wykorzystany w systemie.
public function
setSzablon(
array
$array
)
{
foreach
(
$array
as
$handle
=>
$file
)
{
if
( file_exists(
$this
->path.
$file
) )
{
if
( array_key_exists(
$handle
,
$this
->files ) )
{
$this
->error(
'<b>'
.__METHOD__.
'</b>: Podana zmienna plikowa już istnieje: '
.
$handle
);
}
$this
->files[
$handle
] =
$file
;
}
else
{
$this
->error(
'<b>'
.__METHOD__.
'</b>: Nie ma takiego pliku: '
.
$file
);
}
}
}
Listing 33: Metoda setSzablon
Metoda setSzablon sprawdza najpierw, czy dany plik istnieje. Jeśli tak, zostaje zapisany do
tablicy przechowującej pliki szablonów, na których aktualnie operuje system. Kolejne szablony
można wywołać w dowolnym momencie, dzięki czemu można je w sobie zagnieżdżać. Po
zdefiniowaniu szablonu, treści przekazywane z systemu trafiają tylko do tego szablonu, dopóki nie
zostanie on zamknięty, lub nie zostanie zdefiniowany następny szablon.
49
$this
->tpl->setZmienna(
array
(
'TRANSACTIONS'
=>
$transactions
,
'STARTDATE'
=>
$startTime
) );
Listing 34: Przypisanie wartości zmiennym szablonowym
Aby uzupełnić szablon o treści, stosuje się trzy konstrukcje, jedną z nich jest metoda
setZmienna, zamieniająca zdefiniowane w szablonie zmienne na treści przekazane z systemu.
public function
setZmienna(
array
$array
)
{
$handle
=
$this
->lastHandle();
$this
->replace[
$handle
] = ( !is_array(
$this
->replace[
$handle
] ) ) ?
array
() :
$this
->replace[
$handle
];
foreach
(
$array
as
$variable
=>
$value
)
{
if
( strtoupper(
$variable
) ==
$variable
)
{
if
( !array_key_exists(
$variable
,
$this
->replace[
$handle
] ) )
{
$this
->replace[
$handle
][
$variable
] =
$value
;
}
else
{
$this
->error(
'<b>'
.__METHOD__.
'</b>: Podana zmienna już istnieje: '
.
$variable
);
}
}
else
{
$this
->error(
'<b>'
.__METHOD__.
'</b>: Proszę podać nazwę zmiennej używając dużych liter!'
.
$variable
);
}
}
}
Listing 35: Metoda setZmienna
Do metody można przekazać wartości dla kilku zmiennych jednocześnie. Każda z nich jest
zapisywana do tablicy zmiennych i ich wartości aktualnego szablonu, chyba, że dana zmienna
została już ustawiona. System zwraca wtedy błąd, jako, że wartość jednej zmiennej może być
ustawiona tylko raz. Zdefiniowana w szablonie zmienna zawarta jest w nawiasie klamrowym w
formie: {NAZWA_ZMIENNEJ}.
$this
->tpl->setBlok(
'month'
,
array
(
'ID'
=>
$i
) );
Listing 36: Tworzenie bloku
Drugą konstrukcją jest metoda setBlok, dzięki której można tworzyć różnego rodzaju listy, lub
zablokować wyświetlanie całego fragmentu szablonu.
public function
setBlok(
$handle_blok
,
array
$array
)
{
$handle
=
$this
->lastHandle();
$i
= count(
$this
->blocks[
$handle
] );
$this
->blocks[
$handle
][
$i
][
'name'
] =
$handle_blok
;
$this
->blocks[
$handle
][
$i
][
'vars'
] =
$array
;
}
Listing 37: Metoda setBlok
Ponieważ jeden blok może, a by utworzyć listę, powinien być wywoływany, wielokrotnie, nie
sprawdza się, czy dany blok został już zdefiniowany. Do tablicy bloków dla danego szablonu
dopisywane są po prostu kolejne wiersze bloku, oraz jego zmiennych. konstrukcji bloku w szablonie
przedstawiona jest na listingu 38.
<!-- BEGIN nazwa_bloku -->
<
b
>
Zawartość bloku
<
u
>
{ZMIENNA_BLOKU}
</
u
></
b
>
<!-- END nazwa_bloku -->
Listing 38: Konstrukcja bloku w szablonie
50
Bloki mogą być zagnieżdżane w sobie, jak również mogą zawierać zmienne.
$this
->tpl->closeSzablon(
'STEPS'
);
Listing 39: Zamknięcie szablonu i przypisanie go do zmiennej innego szablonu.
Trzecią konstrukcją jest closeSzablon. Zamyka ona aktualnie używany szablon, po czym
wygenerowaną treść przypisuje do zmiennej szablony wywołanego poprzednio.
public function
closeSzablon(
$variable
)
{
$this
->readFile();
$this
->compileBlok();
$this
->parseSzablon();
$this
->cleanSzablon();
$this
->unsetHandle();
$this
->setZmienna(
array
(
$variable
=>
$this
->file ) );
}
Listing 40: Metoda closeSzablon
Szablon jest najpierw wczytywany. Następnie są kompilowane bloki, po czym w zmienne
zdefiniowane w szablonie zostają wstawione przypisane wartości. Metoda cleanSzablon czyści
otrzymaną treść z niewykorzystanych konstrukcji szablonowych, a metoda unsetHandle usuwa
wszystkie przekazane dla tego szablonu treści. Na koniec zostaje on przypisany do zmiennej
poprzedniego szablonu.
$this
->tpl->printTemplate();
Listing 41: Zakończenie pracy z szablonem
Szablon można zamknąć również metodą printTemplate, jedyną różnicą pomiędzy metodą
printTemplate a closeSzablon jest to, że printTemplate nie przypisuje zawartości szablonu do innego
szablonu, a wyświetla jego zawartość na ekranie.
//Szukamy wszystkich bloków w pliku
preg_match_all(
'/<!-- BEGIN ([0-9a-z_]+) -->/'
,
$this
->file,
$blocks
);
if
( count(
$blocks
[
'1'
]) >
0
)
{
//Wyciągamy kod bloku
foreach
(
$blocks
[
'1'
]
as
$key
=>
$blockName
)
{
if
( preg_match(
'/<!-- BEGIN '
.
$blockName
.
' -->(.*)<!-- END '
.
$blockName
.
' -->/s'
,
$this
->file,
$blockFile
) )
{
$blockFiles
[
$blockName
][
'file'
] =
$blockFile
;
//Znajdujemy wszystkie podbloki
preg_match_all(
'/<!-- BEGIN ([0-9a-z_]*) -->/s'
,
$blockFile
[
'0'
],
$dependers
);
foreach
(
$dependers
[
'1'
]
as
$childrenKey
=>
$childrenName
)
{
if
(
$childrenName
==
$blockName
)
{
$supremeBlocks
[
$childrenName
] =
1
;
}
else
{
$childrenBlocks
[
$childrenName
] =
$blockName
;
}
}
}
}
Listing 42: Wyszukiwanie bloków w szablonie i ustalanie ich hierarchii
51
Podczas kompilacji bloku, najpierw znajdowane są w nim wszystkie zdefiniowane bloki, oraz
określane są istniejące podbloki.
//odwracamy tablicę zależności bloków i podbloków, w tablicy supremeBlock zostają tylko bloki główne.
if
( is_array(
$childrenBlocks
) )
{
foreach
(
$childrenBlocks
as
$childrenBlock
=>
$parentBlock
)
{
$dependerBlock
[
$parentBlock
][
$childrenBlock
] =
1
;
$blockFiles
[
$parentBlock
][
'file'
][
'1'
] = str_replace(
$blockFiles
[
$childrenBlock
][
'file'
][
'0'
],
'{'
.
$childrenBlock
.
'}'
,
$blockFiles
[
$parentBlock
][
'file'
][
'1'
] );
unset
(
$supremeBlocks
[
$childrenBlock
] );
}
}
Listing 43: Określenie bloków głównych
Następnie, określane jest, które bloki są blokami głównymi, a we wszystkich blokach
zawierających podbloki treść tych podbloków zamieniana jest na odpowiednią zmienną.
//uzupełniamy odpowiednie podbloki zmiennymi i zapisujemy ich kolejność
if
( is_array(
$this
->blocks[
$handle
]) )
{
foreach
(
$this
->blocks[
$handle
]
as
$row
)
{
$blocksHandles
[] =
$row
[
'name'
];
$tmpString
=
$blockFiles
[
$row
[
'name'
]][
'file'
][
'1'
];
foreach
(
$row
[
'vars'
]
as
$variable
=>
$value
)
{
$tmpString
= str_replace(
'{'
.
$variable
.
'}'
,
$value
,
$tmpString
);
}
$filledBlock
[
$row
[
'name'
]][] =
$tmpString
;
}
}
Listing 44: Uzupełnianie bloków danymi
Kolejną czynnością, jaka następuje, jest wstawienie kolejnych wierszy tabeli przechowującej
dane przesłane dla bloków danego szablonu w odpowiednie bloki.
//łączymy bloki w jeden ciąg
while
(
$blocksHandles
)
{
$currentBlock
= array_pop(
$blocksHandles
);
$tmpString
= array_pop(
$filledBlock
[
$currentBlock
] );
if
( is_array(
$dependerBlock
[
$currentBlock
] ) )
{
foreach
(
$dependerBlock
[
$currentBlock
]
as
$children
=>
$set
)
{
$tmpString
= str_replace(
'{'
.
$children
.
'}'
,
$composeBlock
[
$children
],
$tmpString
);
unset
(
$composeBlock
[
$children
] );
}
}
$composeBlock
[
$currentBlock
] =
$tmpString
.
$composeBlock
[
$currentBlock
];
}
Listing 45: Łączenie podbloków z blokami, i łączenie ich w listy
Następnie bloki są łączone ze sobą wedle kolejności ich wywoływania przez system.
Zachowana jest przy tym ich kolejność oraz hierarchia z szablonu.
52
//Wpisanie bloków głównych do pliku
foreach
(
$supremeBlocks
as
$parent
=>
$children
)
{
if
( !is_array(
$childrenBlocks
[
$parent
] ) )
{
$this
->file = str_replace(
$blockFiles
[
$parent
][
'file'
][
'0'
],
preg_replace(
'/\{[A-Z0-9_]+\}/'
,
''
,
$composeBlock
[
$parent
] ),
$this
->file );
}
}
Listing 46: Połączenie bloków z szablonem
Ostatnim krokiem kompilacji bloków jest wpisanie głównych bloków uzupełnionych o
odpowiednie treści w ich miejsce w szablonie.
//Podstawia zmienne w szablon
private function
parseSzablon()
{
$handle
=
$this
->lastHandle();
if
( is_array(
$this
->replace[
$handle
] ) )
{
foreach
(
$this
->replace[
$handle
]
as
$variable
=>
$value
)
{
$this
->file = str_replace(
'{'
.
$variable
.
'}'
,
$value
,
$this
->file );
}
}
}
Listing 47: Metoda parseSzablon
Gdy bloki zostały już skompilowane i naniesione na szablon, zostają uzupełnione zmienne
zdefiniowane w szablonie.
//Czyści szablon ze zmiennych
private function
cleanSzablon()
{
$this
->file = preg_replace(
'/\{[A-Z0-9_]+\}/'
,
''
,
$this
->file );
}
Listing 48: Metoda cleanSzablon
Na koniec szablon zostaje oczyszczony z niewykorzystanych zmiennych. Metoda ta nie czyści
z konstrukcji blokowych, ponieważ te, są automatycznie czyszczone w metodzie kompilującej bloki.
<
div
id
=
"title"
>
<
a
href
=
""
title
=
"{MAIN_TITLE}"
>
{MAIN_TITLE}
</
a
>
<!-- BEGIN path -->
»
<
a
href
=
"{PATH_URL}"
title
=
"{PATH_TITLE}"
>
{PATH_TITLE}
</
a
>
<!-- END path -->
</
div
>
Listing 49: Fragment szablonu header.szb
Przedstawiony na listingu 49 fragment szablonu header.szb odpowiada za wyświetlanie ścieżki
w aplikacji. Ścieżka ta, oprócz pierwszego elementu, jest różna na każdym kolejnym ekranie
aplikacji. Szablon wczytywany w listingu 32 służy jako ogólny szkielet modułu generacji, w nim
zagnieżdżane są szablony odpowiedzialne za wygląd każdego z kroków generacji. Umieszczane są
one w miejscu zmiennej {STEPS} (listing 39).
53
6. Testy
6.1 Test działania systemu
Cel testu: Sprawdzenie działania systemu na serwerze WWW, miejscu, które jest jego
środowiskiem pracy.
Oczekiwany rezultat: Prawidłowe wyświetlenie strony logowania.
Przebieg testu: Skopiowano folder z plikami systemu do folderu C:/www/, gdzie
przechowywane są treści www obsługiwane przez serwer apache. Sprawdzono działanie systemu i
nie stwierdzono problemów. Ekran logowania wyświetla się poprawnie, co przedstawiono na
rysunku 28.
Rysunek 28: Ekran logowania systemu
6.2 Test trybów logowania użytkownika
Cel testu: Poprawne zalogowanie do systemu z opcją zapamiętaj, jak i bez tej opcji.
Oczekiwany rezultat: Wyświetlenie strony powitalnej. W trybie bez opcji zapamiętania w
przeglądarce nie powinno być cookie nazwanego autologowanie. W trybie z zaznaczoną opcją,
cookie takie powinno wystąpić.
Przebieg testu: W pierwszej kolejności przetestowano logowanie bez zaznaczonej opcji
autologowania. W celu zalogowania skorzystano z użytkownika o loginie ‘admin’ (rys.29).
Rysunek 29: Logowanie do systemu bez opcji Zapamiętania
54
Jak widać na powyższym obrazku, opcja ‘Zapamiętaj’ nie została zaznaczona. Logowanie
przebiegło pomyślnie i wyświetlił się ekran powitalny przedstawiony na rysunku 30.
Rysunek 30: Ekran powitalny
W celu zweryfikowania trybu logowania otwarto spis ciasteczek zapisanych przez system w
przeglądarce. Jak widać na poniższym rysunku, zostało zapisane tylko ciasteczko sesji
przedstawione na rysunku 31.
Rysunek 31: Spis ciasteczek logowania bez opcji Zapamiętaj
By przeprowadzić kolejny krok testu, wylogowano się z systemu. W ekranie logowanie
wprowadzono te same dane, co poprzednim razem, zaznaczając tym razem opcję Zapamiętaj,
przedstawioną na rysunku 32.
Rysunek 32: Logowanie z opcją Zapamiętaj
Logowanie zakończyło się sukcesem i wyświetlił się ekran powitalny (rys. 23). W celu
zweryfikowania trybu, wyświetlono spis plików cookie zapisanych przez system w przeglądarce
przedstawiony na rysunku 33.
Rysunek 33: Spis plików cookie z ciasteczkiem autologin
Przeprowadzony test spełnił oczekiwania i zakończył się sukcesem.
55
6.3 Test funkcji manipulacji danymi
Cel testu: Sprawdzenie panelu manipulacji danymi Produktów.
Oczekiwany rezultat: Pojawienie się nowego produktu w spisie produktów, po czym nastąpi
jego edycja, a następnie usunięcie.
Przebieg testu: Po zalogowaniu się do systemu wybrano z menu głównego pozycję produkty.
Na Ekranie pojawił się panel manipulacji danymi produktów przedstawiony na rysunku 34.
Rysunek 34: Panel manipulacji danych produktów
W pierwszym wierszu, służącym do dodawania nowych produktów do bazy danych
wprowadzono następujące dane:
−
Nazwa: wpisano GeForce 2 MX
−
Kategoria: wybrano „Karty graficzne”
−
Producent: wybrano „nVivdia”
−
Cena: wpisano 99
56
Rysunek 35: Dodawanie nowego produktu
Po wciśnięciu przycisku „Zapisz!”, nowy produkt pojawia się w bazie danych (rys.36).
Rysunek 36: Nowy produkt w bazie danych
Tym samym pojawia się również w spisie produktów (rys.37).
Rysunek 37: Nowy produkt w spisie treści
Jak widać, pierwszy etap testu przebiegł pomyślnie, kolejnym etapem, będzie zmiana
wprowadzonego produktu. Zmienione zostaną następujące pola:
−
Nazwa: GeForce 2 MX 200
−
Cena: 89.99
Rysunek 38: Edycja produktów
57
Po zmianie wymienionych pól na powyższe wartości, wciśnięto przycisk „Edytuj”. Dokonane
w formularzu zostały wprowadzone do bazy danych (rys.39).
Rysunek 39: Zmienione dane w bazie danych
Wprowadzone zmiany pojawiły się również w spisie produktów, w związku z czym, ten etap
testu również zakończył się powodzeniem. Kolejną czynnością w teście jest usunięcie produktu.
W tym celu naciśnięto przycisk „Usuń”. Na ekranie pokazał się komunikat przedstawiony na
rysunku 40.
Rysunek 40: Komunikat ostrzegający przed przypadkowym usunięciem.
Po potwierdzeniu, produkt zostaje usunięty z bazy danych i tym samym nie pojawi się więcej
w spisie produktów.
6.4 Test generacji danych do analizy
Cel testu: Sprawdzenie panelu generacji danych do analizy.
Oczekiwany rezultat: Wygenerowanie danych transakcyjnych służących do analizy.
Przebieg testu: By wygenerować dane do analizy, po zalogowaniu użytkownik wybiera opcję
generacja z menu głównego systemu. Ponieważ dane zostały już wygenerowane, otrzymano
komunikat przedstawiony na rysunku 39.
58
Rysunek 41: Komunikat o istniejących danych transakcyjnych
Poprzez naciśnięcie przycisku „Tak!” usunięto wygenerowane uprzednio dane transakcyjne i
komunikat został zastąpiony przez ekran pierwszego kroku generacji danych do analizy (rys.42).
Wypełniono następujące pola:
−
Ilość miesięcy: zmieniono domyślną wartość 24 na 26
−
Współczynnik zatłoczenia: pozostawiono domyślną wartość domyślną 60
Rysunek 42: Krok pierwszy generacji danych transakcyjnych
Po przejściu do następnego ekranu (rys.43), ustawiono wartości współczynniki wzrostu w
następujący sposób:
−
Styczeń: -1
−
Luty: 0
−
Marzec: 0
−
Kwiecień: 1
−
Maj: 2
−
Czerwiec: -1
−
Lipiec: 0
−
Sierpień: 0
−
Wrzesień: 1
59
−
Październik: 0
−
Listopad: 1
−
Grudzień 2
Rysunek 43: Krok drugi generacji danych transakcyjnych
Na podstawie system wylicza dla każdego miesiąca ilość transakcji, które będzie generować
raport przedstawiony na rysunku 44.
Rysunek 44: Krok trzeci generacji danych transakcyjnych
Następnie został naciśnięty przycisk „Generuj zakupy”. O powodzeniu informuje nas
komunikat systemowy przedstawiony na rysunku 45.
60
Rysunek 45: Komunikat o wygenerowanych danych
6.5 Test raportowania
Cel testu: Przetestowanie opcji przeglądania raportów.
Oczekiwany rezultat: Poprawne wyświetlenie testu, zgodnego z wygenerowanymi w
rozdziale 6.4 danymi.
Przebieg testu: Po zalogowaniu się do systemu, wybrano z menu głównego opcję Raporty. Z
listy raportów wybrano raport: „Roczne zestawienie sprzedaży” (rys.46).
Rysunek 46: Wybór raportu
Następnie ustawiono parametry dla raportu. Spośród zboru zawierającego lata 2005, 2006,
2007 i wartość domyślną „All” wybrano rok 2006.
61
Rysunek 47: Ustawianie parametrów raportu
Po ustawieniu parametrów (rys.47), wciśnięto przycisk „Zobacz raport:…”, który otwiera
ekran z wygenerowanym raportem. Raport zawiera ilość zamówień miesięcznych, oraz ich wartość.
Wykres przedstawiony na rysunku 48 obrazuje zmieniającą się ilość zamówień.
62
Rysunek 48: Raport rocznego zestawienia sprzedaży
63
7. Podsumowanie
System stworzony w pracy dyplomowej stanowi realizacje pomostu pomiędzy językiem php,
który jest popularnym narzędziem przy tworzeniu internetowych aplikacji typu e-commerce, a
technologią OLAP, która jest jednym z wydajniejszych i wygodniejszych rozwiązań przeznaczonym
dla analizy biznesowej.
System zaprojektowano i wykonano w oparciu o model obiektowy. Dzięki modelowi
obiektowemu w oparciu o który zaprojektowano i wykonano system, jak również wykorzystaniu idei
systemu szablonów, i innych standardów programowania obiektowego, po odrzuceniu modułów
odpowiedzialnych za generację danych i ją wspomagających, jest możliwe zintegrowanie go z
istniejącym już sklepem internetowym.
Stworzono jasne i przejrzyste raporty obrazujące zachodzącą w systemie sprzedaż i
pomagające w podejmowaniu biznesowych decyzji. Dzięki czytelnie skonstruowanym tabelom,
prostym wykresom oraz parametryzacji, raporty te stanowią doskonałe źródło informacji o
procesach zachodzących w sprzedaży jak również zmieniających się trendach.
Zaprojektowano wygodny, ergonomiczny i przejrzysty interfejs użytkownika. Dzięki swojej
prostocie, podkreśleniu istotnych elementów, a także zastosowaniu ścieżki, użytkownik zawsze wie,
w którym miejscu systemu się znajduje i nie ma możliwości zagubienia.
Prezentowane przez system możliwości, są zaledwie ułamkiem tego, co można uzyskać
stosując obie technologie, jednak w sposób wyraźny je sygnalizują. Z powodu ograniczeń
czasowych zrezygnowano z bezpośredniego połączenia systemu z bazą danych typu OLAP. W
zamian za to skorzystano z usługi SQL Server Reporting Services, dostępnej razem z SQL Server
2005, który wymaga serwera IIS instalowanego na systemach Microsoft Windows.
64
8.Bibliografia
1. Gorawski Marcin – „Ocena efektywności architektur OLAP” (
informatyka.pl/article/show/430
2. Reed Jacobson – „Microsoft SQL Server 2005 Analysis Services krok po kroku”
3. Dr inż. Damian Dudek – wykłady na temat “Projektowanie Baz Danych”
4. Dr inż. Paweł Myszkowski – wykłady na temat „Analityczne Bazy Danych”
5. Dokumentacja PHP (
6. Microsoft Corporation – Books Online – Microsoft SQL Server 2005
7. Andi Gutmans – What’s new in PHP 5? (
http://devzone.zend.com/node/view/id/1714
8. osCommerce (
9. JShop E-Commerce (
10. Eclipse (
11. Sybase Power Designer 11 Evaluation (
http://www.sybase.com/detail?id=1033602
)
65