Nastanak
Krajem 2001-ve godine radio sam "Idejnu studiju o komunikacijskom i informatičkom poboljšanju rada SSUTH" (u izradi studije sudjelovali su: Vesna Dejanović, Branko Sinković i Saša Šujica). Jedan od zaključaka studije govorio je o promjeni postojećih stranica, tada statičkih (uz dodatak ankete i diskusije) u dinamički sustav s raznim sadržajima, uključujući elemente grupnog rada (engl. groupware-a). Studija je cijeli posao razlomila u tri faze, a unutar prve faze trebalo je omogućiti jednostavno ažuriranje tekstova na site-u. Kako nitko od uposlenika SSUTH-a nije savladao tehnologiju izrade stranica, dizajn i ažuriranje stranica radio je Emir Kasumagić.
Tijekom ljeta 2003-ge godine sazrelo je vrijeme za implementaciju prvog dijela, koji je trebao omogućiti upravljanje sadržajem. Rad na novoj verziji započeo je u 10-tom mjesecu, da bi do kraja 11-tog mjeseca prva verzija bila u funkciji.
Razvoj
Projekt je vodio Branko Banda i on je dogovorio specifikaciju stvari koje se izvode u prvoj fazi, a koje ostaju za slijedeće verzije.
Sve stranice (engl. site) i struktura tablica u bazi, napravljene su tako da je moguće paralelno imati više kopija site-a, kako bi se omogućilo testiranje i uvježbavanje članova na "radnoj" verziji.
Tijek radnih postupaka (engl. workflow)
Razlikujemo dvije bitne grupacije korisnika: autora članka i urednika tekstova. Svaka grupa korisnika tipično odrađuje svoj dio posla. Kako slika vrijedi 1000 riječi, najbolje je pogledati skice iz dokumentacije projekta:
Autor ne može sam objaviti članak, to može samo urednik. Autor može mijenjati svoj članak do trenutka kad ga pošalje uredniku. Urednik ima sva prava odlučivanja o sudbini članka.
Tehnologija
Izabrana je LAMP tehnologija, a važni faktori u izboru bili su cijena i procjena izvedivosti sustava u danoj tehnologiji. Aktualne verzije u vrijeme izrade su: Apache 2.0.48, MySQL 4.0.16, PHP 4.3.4.
Apache
Za posluživanje zahtjeva od strane korisnika koristi se Apache web server, ali mogao bi se koristiti bilo koji HTTP 1.1 compliant web server.
MySQL
Za spremanje podataka koristi se MySQL RDBMS sustav. Od specifičnosti MySQL RDBMS-a, koristi se auto_increment za umjetne primary key-eve. Za saznavanje vrijednosti zadnjeg unesenog podatka koristi se LAST_INSERT_ID() funkcija.
PHP
Koriste se PHP ekstenzije za pristup MySQL RDBMS-u te GD library (php_gd2) za manipulaciju slika (izradu umanjenih slika). Iz PEAR-a (standardne biblioteke PHP-a) upotrijebljen je PEARDB dio za apstrakciju pristupa spremištu podataka. Dodatno, za izradu prezentacijskog sloja koristi se Smarty Template Engine (verzija 2.5.0).
JS/CSS
Sadržaj je unošen putem
htmlArea v3.0 komponente, reklamirane kao "besplatni grafički
uređivač teksta" (A free WYSIWYG editor
replacement for <textarea> fields
). htmlArea 3.0 kod je kombinacija
JavaScript-a i CSS2, a radi u IE
verziji 6.0 i Gecko baziranim preglednicima (FireFox 0.7 i Mozilla 1.5 ili
noviji). Unos slika riješen je izradom
zasebne galerije slika (teoretski i drugih multimedijskih sadržaja) koje
su organizirane u kategorije. Kad je slika unesena u galeriju, lako se mogla
uključiti u tekst putem dodatka (engl. plug-in) za htmlArea komponentu.
XHTML 1.0
Stranice su pravljene prema XHTML 1.0 Transitional i CSS2 standardima, te je tako izveden privatni dio site-a. Odstupanje postoji samo na stranici za unos članka (jer se ne može garantirati da je uneseni tekst/html sukladan standardima).
Radno okruženje (engl. Framework)
Kod je organziran prema višeslojnom (engl. three-tier) modelu. Sastoji se od:
- sloja za pristup podacima (engl. Data Access Layer, DAL)
- spone između korisnikovih zahtjeva i spremišta podataka te prezentacije podataka (engl. Bussiness Logic Layer, BLL)
- sloja za prezentaciju podataka korisniku (engl. Presentation Logic Layer, PLL)
Kako bi se olakšao eventualni prelazak na drugu RDBMS tehnologiju, DAL sloj poziva PEARDB funkcije. DAL sloj je, radi jednostavnijeg održavanja, razlomljen na više objekata. Za izradu potrebnih DAL objekata zadužen je DAL_factory objekt (modeliran prema standardnom factory objektu) koji pripremi vezu (engl. connection) prema bazi te imena svih tablica. Tijekom opsluživanja korisnikovog zahtjeva otvorena je jedna veza prema bazi (koju koriste svi BLL objekti). Sve zahtjeve prema bazi možemo karakterizirati kao select,execute,get_one i get_row tipove upita. Execute tip upita koristi se za standardne SQL izraze INSERT, UPDATE i DELETE kod kojih se kao rezultat očekuje boolean true ili false vrijednost.
Čitanje podataka iz baze je, zbog efikasnosti, podijeljeno na tri tipa: select, get_one i get_row. Upit get_one vraća pojedinačnu traženu vrijednost (ili false, ako je došlo do greške). Upit get_row vraća pojedinačni tuple (row) podataka, a select može vratiti od 0 do N redova podataka. Svi upiti vraćaju boolean false ako je došlo do greške.
Funkcionalnost DAL sloja podijeljena je na logične dijelove, a svaki dio ima objekte reader i writer. U slučaju kad nam treba read-only pristup, BLL objekt instancira samo DAL-reader objekt.
Jezgru prezentacijskog sloja (PLL) čine PLL objekti interface i xhtml_page, te Smarty template engine. Funkcionalnost PLL-a razbijena je na dva dijela (interface i xhtml_page) kako bi se zajednički dio (potreban raznim tehnologijama) nalazio u jednoj logičnoj cjelini (interface). U zajedničkom dijelu nalaze se npr. funkcije za provjeru prava pristupa i lokalizaciju, dok je specifičnost za (X)HTML tehnologiju stavljena u xhtml_page objekt (npr. funkcije za enable/disable cache-a te prosljeđivanje podataka Smarty-ju). Ako se pojavi potreba za drugim tehnologijama (npr. WAP/WML) potrebno je izraditi pandan xhtml_page objektu.
Smarty template engine je korišten za razdvajanje prezentacijske logike i "donjih slojeva". Ovakav način NE omogućava potpuno odvajanje grafičkog dizajna i bussiness-logike, cilj mu je odvajanje prezentacijske logike i biznis-logike. Suptilna razlika je u činjenici da izrada npr. selectbox-a ili radio buttona pripada prezentacijskoj logici, dok bussiness logika treba pripremiti polje (ili objekt) s vrijednostima koje prezentacija prikazuje. U pravilu, prezentacijska logika tada obrađuje pripremljeno polje podataka i iz njega stvara sučelje prema korisniku.
Organizacija diska
U osnovi, imamo barem dva logička područja na disku. Jedno područje su stranice koje se prikazuju korisniku (dakle, sve ono što treba imati svoj URL i što web server, na korisnikov zahtjev, isporučuje), a drugo područje čine kofiguracijski podaci, DAL, BLL i PLL objekti, Smarty template-i, temporary prostor itd. (područje gdje korisnik ne smije pristupiti). Smarty template engine traži direktorije template,template_c i cache. Direktorij template i struktura ispod tog direktorija sadrži sve template za izradu stranica.
Galerija slika
Kod unosa slike u galeriju, korisnik određuje kategoriju, naslov i opis slike. Ako je proces prenosa na server (engl. upload) uspješno napravljen, kontrolira se najveća dopuštena veličina slike i njen format. Ako je sve u redu, sustav radi manju sliku (engl. thumbnail) koju koristi kod prikaza svih slika pojedine kategorije. Ta umanjena slika dimenzija je najviše 100x100 točkica (engl. pixel), pri čemu se čuva originalni omjer širine i visine slike (engl. aspect ratio), kako ne bi došlo do izobličenja. Umanjena slika dobiva prefiks koji je naveden u parametrima i smješta se u isti direktorij kao i original.
Smještaj slike u skladište
Slike se smještaju u skladište (engl. storage) čiji korjenski direktorij (engl. root) je naveden u parametrima. Može postojati više skladišta (treba otvoriti novo ako smo ostali bez mjesta na disku), pa postoji parametar koji određuje aktivno skladište (ono u koje se spremaju nove slike).
Sustav popunjava skladište tako da popuni aktivni direktorij (koji se pamti u parametrima), smještajući u njega najviše dvostruki broj datoteka navedenih u parametru album_max_files_per_dir (zato jer se umanjene slike ne broje). Kad je popunjen aktivni direktorij, sustav radi novi poddirektorij za popunu slijedećim redom (u primjeru je pretpostavljena vrijednost parametra album_max_subdirs_per_dir = 1000):
- A1/, A2/, A3/, ... A1000/, popunjavanje prve razine direktorija
- A1/A1/, A1/A2/, A1/A3/, ... Ai/A1000/, popunjavanje druge razine direktorija
- A2/A1/, A2/A2/, A2/A3/, ... A2/A1000/, za svaki direktorij na prvoj razini
- A3/A1/, A3/A2/, A3/A3/, ... A3/A1000/,
- ...
- Ai/A1/, Ai/A2/, Ai/A3/, ... Ai/A1000/,
- ...
- A1000/A1/, A1000/A2/, A1000/A3/, ... A1000/A1000/,
- A1/A1/A1/, A1/A1/A2/, A1/A1/A3/ ... A1/A1/A1000/, popunjavanje treće razine direktorija
- A1/A2/A1/, A1/A2/A2/, A1/A2/A3/ ... A1/A2/A1000/, za svaki direktorij na drugoj razini
- A1/A3/A1/, A1/A3/A2/, A1/A3/A3/ ... A1/A3/A1000/,
- ...
- A1/Aj/A1/, A1/Aj/A2/, A1/Aj/A3/ ... A1/Aj/A1000/,
- ...
- A1/A1000/A1/, A1/A1000/A2/, A1/A1000/A3/ ... A1/A1000/A1000/,
- A2/A1/A1/
- itd
Osnova algoritma je otvaranje nove razine u trenutku kad su iscrpljene sve mogućnosti na postojećoj razini. Parametri koji određuju broj datoteka u direktoriju i broj poddirektorija postavljeni su, konzervativno, na 1000 jer su neki (uglavnom stariji) datotečni sustavi pokazivali znatno usporenje kod velikog broja datoteka.
U slučaju brisanja slike iz galerije, sustav ne radi stvarno brisanje, već premješta original sliku (briše se samo umanjena slika) u zasebno skladište, prikladno nazvano arhiva.
Parametri galerije slika
U konfiguracijskoj tablici, slijedeći parametri utječu na rad galerije slika:
- album_max_upload_size: određuje koliko može biti velika slika koja se unosi (100 K)
- album_max_files_per_dir: koliko najviše datoteka može biti u pojedinom direktoriju (1000)
- album_max_subdirs_per_dir: koliko najviše direktorija može biti u pojedinom direktoriju (1000)
- album_allowed_mime_types: koji tipovi datoteka se mogu unositi u galeriju (image/gif, image/jpeg, image/pjpeg, image/jpg, image/png)
- album_thumbnail_width: najveća širina umanjene slike
- album_thumbnail_height: najveća visina umanjene slike
- album_thumbnail_prefix: prefiks koji se dodaje umanjenoj slici
- album_storage_root: korjenski direktorij ispod kojeg se nalaze slike
- album_storage_current: pokazivač na aktivni korjenski direktorij
- album_storage_rel_path: aktivni direktorij ispod korijenskog koji se popunjava
- album_storage_files_no: trenutni broj datoteka u aktivnom direktoriju
- album_archive_root: korjenski direktorij arhive
- album_archive_rel_path: aktivni direktorij arhive
- album_archive_current: pokazivač na aktivnu arhivu
- album_archive_files_no: trenutni broj datoteka u aktivnom direktoriju arhive