Administrátorské prostredie rozvrhu FM: Rozdiel medzi revíziami
d (Administrátorské prostredie premiestnená na Administrátorské prostredie rozvrhu FM) |
|||
(6 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených) | |||
Riadok 1: | Riadok 1: | ||
[[Kategória:Študentské práce]][[Kategória:Bakalárske práce]][[Kategória:Informatika]][[Kategória:web]][[Kategória:php]] | [[Kategória:Študentské práce]][[Kategória:Bakalárske práce]][[Kategória:Informatika]][[Kategória:web]][[Kategória:php]] | ||
− | {{Praca_uvod|3|Systém tvorby rozvrhu|Popis systémov pre tvorbu rozvrhu|Návrh systému rozvrhu pre FM TnU AD|Administrátorské prostredie|||||||||}} | + | {{Praca_uvod|3|Systém tvorby rozvrhu|Popis systémov pre tvorbu rozvrhu|Návrh systému rozvrhu pre FM TnU AD|Administrátorské prostredie rozvrhu FM|Funkcie administrátorského prostredia||||||||}} |
__TOC__ | __TOC__ | ||
− | |||
− | |||
− | |||
− | + | = = | |
− | |||
− | |||
− | == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | == Prihlásenie do administrátorského rozhrania systému rozvrhFM == | |
− | |||
− | == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Pre prihlásenie do systému slúži jednoduchý HTML formulár. Na vytváranie formulárov v ZF | |
− | + | existuje trieda Zend_Form, ktorá obsahuje metódy na vytváranie všetkých bežných prvkov | |
− | + | formulára. Prvkom sa dajú okrem klasických atribútov priradiť tiež rôzne filtre, podľa ktorých | |
− | + | sa označí formulár ako správne alebo nesprávne vyplnený po jeho odoslaní. | |
− | + | ||
− | == | + | Metóda pre kontrolu odoslaných údajov checkForm() (Kód 2.2) sa nachádza v triede |
− | + | adminLogin a prijíma dva parametre: $login a $password, ktoré obsahujú odoslané | |
− | === | + | prihlasovacie meno a heslo. Najskôr zisťujem, či bol formulár odoslaný metódou POST. |
− | + | Potom kontrolujem správnosť údajov podľa filtrov pridelených k daným prvkom formulára. | |
− | + | Následne porovnávam údaje so správnymi prihlasovacími údajmi. Vzhľadom k tomu, že | |
− | + | do systému bude mať prístup iba veľmi malé množstvo používateľov, sú správne | |
− | + | prihlasovacie údaje uložené ako konštanty triedy obsluhujúcej prihlasovanie. Ak bolo zadané | |
− | + | prihlasovacie meno a heslo správne, nastavím session s informáciou o stave prihlásenia | |
− | + | na hodnotu true. Inak označím prvok formulára pre heslo ako nesprávne vyplnený a pridám | |
− | + | chybová správa, ktorá sa vypíše pod formulárom. Metóda má návratovú hodnotu buď true – | |
+ | pravda, keď prihlásenie prebehlo úspešne, alebo false – nepravda, keď prihlásenie úspešné | ||
+ | nebolo. | ||
+ | <source lang="php"> | ||
+ | public function checkForm($login, $password) | ||
+ | { | ||
+ | if(false == $this->_controller->getRequest()->isPost()) { | ||
+ | return false; | ||
+ | } | ||
+ | if(true == $this->getForm()->isValid($_POST)) { | ||
+ | if(self::LOGIN === $login && self::PASSWORD === $password) { | ||
+ | Zend_Registry::get('sessions')->logged = true; | ||
+ | return true; | ||
+ | } else { | ||
+ | $this->_form->getElement('password')->addError('Nesprávny login alebo heslo!'); | ||
+ | } | ||
+ | } | ||
+ | return false; | ||
+ | } | ||
</source> | </source> | ||
− | + | To, či je používateľ prihlásený alebo nie, sa kontroluje pri každom prístupe do | |
− | + | administrátorského prostredia. Ak používateľ nie je prihlásený a zadá adresu inú, než na | |
− | + | stránku s prihlasovacím formulárom, presmerujem ho na prihlasovaciu stránku. Naopak, ak | |
− | + | používateľ prihlásený je, ale zadá adresu na prihlasovaciu stránku, presmerujem ho na stránku | |
− | alebo | + | s administračným prostredím. Na túto stránku používateľa presmerujem aj pri pokuse |
− | + | o priamy vstup na akúkoľvek inú stránku administrácie, pretože tieto stránky sú prístupné iba | |
− | + | cez AJAX. Prístup cez AJAX sa zisťuje prítomnosťou hlavičky X-Requested-With, ktorú | |
− | + | knižnica jQuery automaticky pridáva do každej AJAXovej požiadavky. Táto kontrola sa | |
− | + | vykonáva v metóde preDispatch() (Kód 2.3) kontroléra AdminController. To, že je táto | |
− | + | metóda volaná pri každom prístupe k danému kontroléru zabezpečuje ZF. | |
− | |||
− | |||
− | |||
<source lang="php"> | <source lang="php"> | ||
− | public function | + | public function preDispatch() |
− | { | + | { |
− | if( | + | $this->_sessions = Zend_Registry::get('sessions'); |
− | + | $action = $this->getRequest()->getActionName(); | |
− | } | + | if(!$this->_sessions->logged && $action != 'login') { |
+ | $this->_redirect('admin/login', array('exit' => true)); | ||
+ | } else if($this->_sessions->logged && $action == 'login') { | ||
+ | $this->_redirect('admin/index', array('exit' => true)); | ||
+ | } else if($action != 'login' && $action != 'index') { | ||
+ | $http = new Zend_Controller_Request_Http(); | ||
+ | if($action != 'logout' && !$http->isXmlHttpRequest()) { | ||
+ | $this->_redirect('admin/index', array('exit' => true)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $this->view->addHelperPath('./application/views/helpers', 'Views_Helpers'); | ||
+ | } | ||
+ | </source> | ||
− | + | === Akcie vykonané po prihlásení === | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Po úspešnom prihlásení sa vykoná synchronizácia tabuľky eval_users s tabuľkou používanou | |
− | + | v systéme evalvácie FM. Keďže prístup z iného serveru do databázy, v ktorej sa originálna | |
− | + | tabuľka nachádza, nie je z bezpečnostných dôvodov povolený, musel som vytvoriť skript, | |
− | + | ktorý vytvorí export<ref>http://fm.tnuni.sk/export_rozvrh/rozvrh_usersExport.php</ref> potrebných údajov a umiestniť ho na server, na ktorom táto databáza beží. Keďže tento export neobsahuje žiadne citlivé informácie, prístup k nemu nie je nijak | |
− | + | zabezpečený a je teda verejne prístupný. Po načítaní exportu tieto údaje porovnávam s údajmi | |
− | + | uloženými v lokálnej tabuľke eval_users a v prípade potreby ich aktualizujem, pridávam | |
− | + | alebo odoberám záznamy. | |
− | |||
− | |||
− | |||
− | + | Následne kontrolujem aktuálnosť uloženej verzie rozvrhu. V prípade, že sa používateľ do | |
− | + | systému prihlási prvýkrát v novom semestri alebo školskom roku, vytvorí sa nový záznam | |
− | + | v archíve aplikácie, do ktorého sa uloží aktuálny stav všetkých tabuliek v databáze a záznamy | |
− | + | v tabuľkách rozvrh_subjectitems, rozvrh_timetable a rozvrh_timetable_extern sa vymažú. | |
− | + | Tabuľka rozvrh_subjectitems sa naplní údajmi z naposledy uloženého záznamu v archíve | |
− | + | z príslušného semestra. Fungovaniu archívu sa budem bližšie venovať v časti [[Funkcie_administrátorského_prostredia#Archiv.C3.A1cia_rozvrhu|4.1.4]]. | |
− | + | Po vykonaní synchronizácie je používateľ presmerovaný do administrátorskej časti aplikácie. | |
− | + | Hneď po vstupe sa zobrazí dialógové okno s hláseniami o výsledku synchronizácie, o stave, | |
− | + | v akom sa rozvrh nachádza, a o prípadnom automatickom uložení záznamu do archívu. | |
− | + | Hlásenie o výsledku synchronizácie obsahuje zoznam pridaných a zmazaných pedagógoch. | |
+ | Pri nových pedagógoch je používateľovi ponúknutá možnosť doplniť im údaje do tabuľky | ||
+ | rozvrh_userdetails, pričom skratka vyučujúceho je povinný údaj. Bez jej určenia všetkým | ||
+ | novým pedagógom nie je možné dialógové okno zatvoriť a pokračovať tak v práci | ||
+ | s aplikáciou. Hlásenie o stave rozvrhu bližšie opíšem v kapitole [[Funkcie_administrátorského_prostredia#Zhrnutie_aktu.C3.A1lneho_stavu_rozvrhu|4.1.6]]. | ||
− | $this-> | + | Po zatvorení dialógového okna s hláseniami môže používateľ pracovať s aplikáciou. Pre |
− | } | + | vykreslenie ovládacích prvkov prostredia potrebujem z databázy vybrať viaceré údaje: |
+ | študijné kombinácie a krúžky, informácie o miestnostiach, typoch predmetov, názvy | ||
+ | predmetov a vyučujúcich priradených k predmetom, zoznam hodín zaradených do rozvrhu, | ||
+ | zoznam hodín nezaradených do rozvrhu a informácie o vyučujúcich. Tieto údaje vyberám | ||
+ | v triede adminIndex. Na prácu s databázou používam ZF triedu Zend_Db a po vybratí údajov | ||
+ | ich triedim a ukladám do poľa kvôli ľahšej práci s nimi. | ||
+ | <source lang="php"> | ||
+ | public function gAddedSubjects() | ||
+ | { | ||
+ | $select = $this->_db->select() | ||
+ | ->from(array('tt' => T_TTABLE), | ||
+ | array('id', 'provides', 'week', 'day', 'hour', 'note', 'room' => 'rozvrh_room_id')) | ||
+ | ->join(array('si' => T_SUBITEMS), | ||
+ | 'tt.rozvrh_subjectItem_id = si.id', | ||
+ | array('hours', 'subject' => 'rozvrh_subject_id', 'type' => 'rozvrh_subjectType_id', 'subclass' => 'rozvrh_subclass_id')) | ||
+ | ->joinLeft(array('t' => T_TEACH), | ||
+ | 'tt.rozvrh_teacher_id = t.id', | ||
+ | array('teacher' => 'eval_user_id')) | ||
+ | ->join(array('s' => T_SUB), | ||
+ | 'si.rozvrh_subject_id = s.id', | ||
+ | array('comb' => 'rozvrh_combination_id')); | ||
+ | $result = $this->_db->fetchAll($select); | ||
+ | $return = array(); | ||
+ | |||
+ | foreach($result as $row) { | ||
+ | if(!isset($return[$row['room']][$row['day']][$row['week']][$row['hour']])) { | ||
+ | $return[$row['room']][$row['day']][$row['week']][$row['hour']] = | ||
+ | array( | ||
+ | 'provides' => $row['provides'], | ||
+ | 'hours' => $row['hours'], | ||
+ | 'teacher' => $row['teacher'], | ||
+ | 'subject' => $row['subject'], | ||
+ | 'comb' => $row['comb'], | ||
+ | 'type' => $row['type'], | ||
+ | 'note' => $row['note'], | ||
+ | 'subclasses' => array() | ||
+ | ); | ||
+ | } | ||
+ | $return[$row['room']][$row['day']][$row['week']][$row['hour']]['subclasses'][$row['subclass']] = $row['id']; | ||
+ | } | ||
+ | return $return; | ||
+ | } | ||
</source> | </source> | ||
− | + | T_TTABLE, T_SUBITEMS, T_TEACH a T_SUB sú konštanty reprezentujúce názvy | |
− | + | tabuliek v databáze. Tieto konštanty sú definované v samostatnom súbore tables.php, ktorý sa | |
− | + | nachádza v konfiguračnom priečinku aplikácie. | |
+ | *T_TTABLE – rozvrh_timetable | ||
+ | *T_SUBITEMS – rozvrh_subjectitems | ||
+ | *T_TEACH – rozvrh_teachers | ||
+ | *T_SUB – rozvrh_subjects | ||
+ | $this->_db je objekt triedy Zend_Db. Táto trieda obsahuje metódy pre prácu s databázou. | ||
+ | Zoznam niektorých metód a ich význam: | ||
+ | *select() – vytvára objekt triedy Zend_Db_Select pre vytvorenie dopytu na databázu typu SELECT | ||
+ | *from($table, $columns) – FROM časť dopytu | ||
+ | **$table – názov tabuľky. Môže byť typu reťazec alebo pole. V prípade typu pole kľúč označuje alias tabuľky a hodnota názov tabuľky | ||
+ | **$columns – zoznam stĺpcov, ktoré sa majú vybrať. Môže byť typu reťazec alebo pole. V prípade poľa môže ísť o asociatívne alebo číselné pole. Ak je pole asociatívne, kľúč znamená alias stĺpca | ||
+ | *join($table, $condition, $columns), joinLeft($table, $condition, $columns) – INNER JOIN, JOIN LEFT časť dopytu | ||
+ | **$table – ako vo from() | ||
+ | **$condition – podmienka spájania výsledkov | ||
+ | **$columns – ako vo from() | ||
+ | *fetchAll($select) – metóda, ktorá vracia všetky záznamy vrátené databázou. Formát vrátených údajov sa dá nastaviť metódou setFetchMode(). Prednastavený formát je asociatívne pole | ||
+ | **$select – dopyt, ktorý sa má vykonať. Môže byť typu reťazec alebo objekt triedy Zend_Db_Select | ||
+ | Po vybratí údajov z databázy sa výsledky prechádzajú v cykle foreach a ukladajú sa do poľa | ||
+ | $return (Kód 2.5) v novom poradí. | ||
<source lang="php"> | <source lang="php"> | ||
− | array( | + | array( |
− | array( | + | T_TTABLE.rozvrh_room_id => array( |
− | ' | + | T_TTABLE.day => array( |
− | + | T_TTABLE.week => array( | |
− | + | T_TTABLE.hour => array( | |
− | + | 'provides' => T_TTABLE.provides, | |
+ | 'hours' => T_SUBITEMS.hours, | ||
+ | 'teacher' => T_TEACH.eval_user_id, | ||
+ | 'type' => T_SUBITEMS.rozvrh_subjectType_id, | ||
+ | 'note' => T_TTABLE.note, | ||
+ | 'data' => array( | ||
+ | T_SUB.rozvrh_combination_id => array( | ||
+ | 'subject' => T_SUBITEMS.rozvrh_subject_id, | ||
+ | 'subclasses' => array( | ||
+ | T_SUBITEMS.rozvrh_subclass_id => T_TTABLE.id | ||
+ | ) | ||
+ | ) | ||
+ | ) | ||
+ | ) | ||
) | ) | ||
− | + | ) | |
− | ); | + | ) |
+ | </source> | ||
+ | Tieto mnohorozmerné polia posúvam v kontroléri do skriptu, ktorý sa stará o vykresľovanie | ||
+ | stránky. V skripte následne postupným prechádzaním polí vytváram jednotlivé ovládacie | ||
+ | prvky. | ||
+ | |||
+ | Keďže na vykreslenie niektorých prvkov využívam JavaScript, musím tieto polia s údajmi | ||
+ | vložiť aj do jeho zdrojového kódu (Kód 2.6). Na túto úlohu používam JSON<ref>http://www.json.org/</ref>, formát | ||
+ | pre prenos dát z jedného programovacieho jazyka do druhého. Premenná akéhokoľvek typu | ||
+ | zakódovaná do formátu JSON je reťazec s pevne danou štruktúrou, z ktorého vie prijímajúci | ||
+ | jazyk vytvoriť premennú rovnakého typu. Ak požadovaný typ v jazyku neexistuje, použije sa | ||
+ | ekvivalentný typ s vlastnosťami čo najviac podobnými pôvodnému typu. | ||
+ | <source lang="html4strict"> | ||
+ | <script type="text/javascript"> | ||
+ | var subjects_added = eval(<?php echo json_encode($this->sub_added);?>); | ||
+ | </script> | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | == Grafický návrh administrátorského prostredia == | |
− | + | ||
− | + | Pri návrhu používateľského rozhrania som kládol dôraz na komfort, prehľadnosť | |
− | + | a intuitívnosť ovládania. Snažil som sa o používanie grafických prvkov a implementovanie | |
− | + | funkcionalít, na ktoré sú používatelia počítača a internetových aplikácií zvyknutí a očakávajú | |
− | + | ich, napr. presúvanie objektov, mazanie objektu stlačením klávesy Delete, zobrazenie | |
− | + | dodatočných informácií o objekte pri presunutí kurzoru nad daný objekt atď. Na zabezpečenie | |
− | + | takýchto funkcií sa na internetových stránkach používa JavaScript. Keďže je mnou | |
− | + | navrhované prostredie pomerne dynamické, potrebuje veľké množstvo JavaScriptového kódu, | |
− | + | čo by sa mohlo prejaviť na plynulosti behu aplikácie. Preto program testujem na posledných | |
− | + | verziách všetkých majoritných internetových prehliadačoch: Firefox, Opera, Internet Explorer | |
− | + | a Chrome. K zrýchleniu behu JavaScriptového kódu pomáha tiež použitie knižnice jQuery, | |
− | + | ktorá je výborne optimalizovaná. | |
− | |||
− | |||
− | |||
− | |||
− | + | Ďalším problémom, ktorý pri použití JavaScriptu môže nastať, je, že v prípade, že ho má | |
− | + | používateľ vypnutý, sa aplikácia stane nepoužiteľnou. Bežným zvykom pri tvorbe | |
+ | internetových stránok je preto snaha písať kód stránky tak, aby bola zabezpečená aspoň jej | ||
+ | základná funkčnosť aj pri vypnutom JavaScripte. Avšak keďže náš systém budú používať iba | ||
+ | tvorcovia rozvrhu, ktorí budú o nutnosti mať zapnutý JavaScript upozornení, nebudem tieto | ||
+ | opatrenia do kódu stránky vkladať. | ||
− | + | Na Obr. 2.2 je znázornená podoba systému v normálnom stave. Pri akciách, ktoré potrebujú | |
− | + | získať dodatočné vstupy od používateľa alebo zobraziť dodatočné informácie, sa na tento účel | |
− | + | zobrazí na obrazovke dialógové okno, ktoré môže mať systémovo-modálny charakter, tzn. | |
− | + | okno bude nad ostatnými prvkami a ostatné prvky stránky sa stanú neaktívnymi až do | |
− | + | zatvorenia dialógového okna. | |
− | + | [[Súbor:mpbc2.2-1.jpg|thumbnail|center|800px|Obr. 2.2 Administrátorské prostredie aplikácie]] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | === Hlavné menu === | |
− | |||
− | + | Vo vrchnej časti stránky sa nachádza hlavné menu (Obr. 2.3). Jedná sa o tzv. drop-down menu | |
− | + | – viacúrovňové menu ovládané pomocou JavaScriptu, ktorého ďalšia úroveň sa zobrazí | |
− | + | po prechode kurzoru nad nadradenou úrovňou a skryje sa po odchode myši z nadradenej | |
− | + | úrovne. | |
− | + | [[Súbor:mpbc2.3.jpg|thumbnail|center|800px|Obr. 2.3 Hlavné menu]] | |
− | + | Položky menu obsahujú odkazy na všetky potrebné funkcie aplikácie, napr.: práca s archívom | |
− | + | rozvrhu, správa krúžkov, správa vyučujúcich atď. Pre vytvorenie a prácu s hlavným menu | |
− | + | som vytvoril triedu My_MainMenu, ktorej konštruktor prijíma ako parameter mnohorozmerné | |
− | + | pole s presne určenou štruktúrou (Kód 2.7), ktoré reprezentuje dané menu. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<source lang="php"> | <source lang="php"> | ||
− | array( | + | array( |
− | + | array( | |
− | + | ‘label’ => ‘Rozvrh’, | |
− | + | ‘js’ => ‘rozvrh’[, | |
− | + | [‘title’ => ‘Správa rozvrhu’,] | |
− | + | [‘img’ => ‘yes.gif’,] | |
− | + | [‘style’ => ‘float:right;’,] | |
− | + | [‘sub’ => array(...)]] | |
− | + | ) | |
− | + | [, array(...)] | |
− | + | ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ) | ||
</source> | </source> | ||
− | + | V nasledujúcom texte je opis štruktúry, ktorá je použitá ako parameter konštruktora triedy | |
+ | My_MainMenu. | ||
+ | *label – zobrazovaný text položky menu | ||
+ | *js – identifikátor položky menu pre JavaScript. Identifikátory nižších úrovní menu sa reťazia s použitím oddeľovača – | ||
+ | *title (nepovinné) – text, ktorý sa zobrazí ako nápoveda pri prechode myši nad prvkom. Ak tento atribút nie je zadaný, použije sa ako text nápovedy hodnota atribútu label | ||
+ | *img (nepovinné) – obrázok, ktorý sa vloží pred text položky | ||
+ | *style (nepovinné) – CSS vlastnosti danej položky. Tento atribút som pridal hlavne kvôli položke Odhlásiť sa, ktorá je od ostatných položiek opticky oddelená | ||
+ | *sub (nepovinné) – zoznam položiek nižšej úrovne | ||
− | + | === Zoznam hodín zaradených do rozvrhu === | |
− | + | ||
− | + | Zoznam hodín zaradených do rozvrhu (Obr. 2.4) je tvorený tabuľkou, ktorá obsahuje všetky | |
− | + | vyučovacie hodiny s určeným časom a učebňou. Stĺpec tabuľky určuje hodinu, riadok učebňu, | |
− | + | v ktorej sa výučba koná. Každý riadok učebne je rozdelený na dve časti, horná časť znamená | |
− | + | párny týždeň, spodná časť nepárny. Ak sa výučba opakuje každý týždeň, hodina presahuje | |
− | + | obe polovice. | |
+ | |||
+ | Nad tabuľkou sa nachádzajú záložky na zmenu dňa, pre ktorý sa bude tvoriť rozvrh. | ||
+ | Pre každý deň je vytvorená samostatná tabuľka, pričom je zobrazená vždy len tabuľka | ||
+ | prislúchajúca k aktuálne vybratému dňu. Odkazom v záložke napravo sa prepína do správy | ||
+ | rozvrhu externých študentov, ktorá má iné prostredie. | ||
+ | |||
+ | Bližší popis buniek s jednotlivými hodinami uvediem v kapitole [[Funkcie_administrátorského_prostredia#Spr.C3.A1va_hod.C3.ADn_zaraden.C3.BDch_do_rozvrhu|4.1.3]]. | ||
+ | [[Súbor:mpbc2.4.jpg|thumbnail|center|800px|Obr. 2.4 Zoznam hodín zaradených do rozvrhu]] | ||
+ | === Zoznam hodín nezaradených do rozvrhu === | ||
− | + | Zoznam hodín nezaradených do rozvrhu (Obr. 2.5) obsahuje bloky vyučovacích hodín, ktoré | |
− | + | boli do systému pridané, ale ešte nebola určená ich hodina a miestnosť výučby. Pri vstupe | |
− | + | do administrátorského prostredia sa nachádza v ľavom dolnom rohu obrazovky. Jeho pozícia | |
− | + | je daná fixne, to znamená, že pri rolovaní stránky zostáva zoznam na mieste. Dá sa však | |
− | + | presúvať uchopením za hornú časť alebo tiež dvojklikom kdekoľvek na stránku – zoznam sa | |
− | + | presunie do danej výšky. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | V spodnej časti sa nachádza zoznam študijných odborov a ich ročníkov. Farba položiek | |
+ | korešponduje s farebným označením buniek v tabuľke hodín zaradených do rozvrhu. V hornej | ||
+ | časti sa nachádza zoznam predmetov, ktoré sú k vybranému odboru a ročníku pridelené. | ||
+ | Jednotlivé predmety sú tvorené systémom záložiek podobne ako prepínanie dní. | ||
+ | [[Súbor:mpbc2.5.jpg|thumbnail|center|800px|Obr. 2.5 Minimalizovaný zoznam hodín nezaradených do rozvrhu]] | ||
+ | [[Súbor:mpbc2.6.jpg|thumbnail|center|800px|Obr. 2.6 Maximalizovaný zoznam hodín nezaradených do rozvrhu]] | ||
+ | Kvôli veľkosti zoznamu som sa rozhodol pridať mu funkciu minimalizácie a maximalizácie, | ||
+ | takže po vybratí predmetu sa zobrazí stredná časť (Obr. 2.6), v ktorej sa nachádzajú jednotlivé | ||
+ | nezaradené hodiny. Naľavo sú typy predmetov, napravo je zoznam krúžkov vo zvolenom | ||
+ | odbore a ročníku. Tieto prvky sú taktiež tvorené systémom záložiek, aj keď pri nich som | ||
+ | na rozdiel od ostatných záložiek nemohol použiť hotový systém z knižnice jQuery UI kvôli | ||
+ | ich vertikálnej polohe. V prípade, že sa vyberie typ predmetu prednáška, zoznam krúžkov sa | ||
+ | skryje, pretože prednášky sa pridávajú pre všetky krúžky naraz. Medzi typmi predmetov | ||
+ | a krúžkami sa nachádzajú jednotlivé nepriradené predmety rozdelené podľa dĺžky výučby. | ||
<references/> | <references/> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |
Aktuálna revízia z 19:33, 23. júl 2010
1. | Popis systémov pre tvorbu rozvrhu |
2. | Návrh systému rozvrhu pre FM TnU AD |
3. | Administrátorské prostredie rozvrhu FM |
4. | Funkcie administrátorského prostredia
|
Obsah
Prihlásenie do administrátorského rozhrania systému rozvrhFM
Pre prihlásenie do systému slúži jednoduchý HTML formulár. Na vytváranie formulárov v ZF existuje trieda Zend_Form, ktorá obsahuje metódy na vytváranie všetkých bežných prvkov formulára. Prvkom sa dajú okrem klasických atribútov priradiť tiež rôzne filtre, podľa ktorých sa označí formulár ako správne alebo nesprávne vyplnený po jeho odoslaní.
Metóda pre kontrolu odoslaných údajov checkForm() (Kód 2.2) sa nachádza v triede adminLogin a prijíma dva parametre: $login a $password, ktoré obsahujú odoslané prihlasovacie meno a heslo. Najskôr zisťujem, či bol formulár odoslaný metódou POST. Potom kontrolujem správnosť údajov podľa filtrov pridelených k daným prvkom formulára. Následne porovnávam údaje so správnymi prihlasovacími údajmi. Vzhľadom k tomu, že do systému bude mať prístup iba veľmi malé množstvo používateľov, sú správne prihlasovacie údaje uložené ako konštanty triedy obsluhujúcej prihlasovanie. Ak bolo zadané prihlasovacie meno a heslo správne, nastavím session s informáciou o stave prihlásenia na hodnotu true. Inak označím prvok formulára pre heslo ako nesprávne vyplnený a pridám chybová správa, ktorá sa vypíše pod formulárom. Metóda má návratovú hodnotu buď true – pravda, keď prihlásenie prebehlo úspešne, alebo false – nepravda, keď prihlásenie úspešné nebolo.
public function checkForm($login, $password)
{
if(false == $this->_controller->getRequest()->isPost()) {
return false;
}
if(true == $this->getForm()->isValid($_POST)) {
if(self::LOGIN === $login && self::PASSWORD === $password) {
Zend_Registry::get('sessions')->logged = true;
return true;
} else {
$this->_form->getElement('password')->addError('Nesprávny login alebo heslo!');
}
}
return false;
}
To, či je používateľ prihlásený alebo nie, sa kontroluje pri každom prístupe do administrátorského prostredia. Ak používateľ nie je prihlásený a zadá adresu inú, než na stránku s prihlasovacím formulárom, presmerujem ho na prihlasovaciu stránku. Naopak, ak používateľ prihlásený je, ale zadá adresu na prihlasovaciu stránku, presmerujem ho na stránku s administračným prostredím. Na túto stránku používateľa presmerujem aj pri pokuse o priamy vstup na akúkoľvek inú stránku administrácie, pretože tieto stránky sú prístupné iba cez AJAX. Prístup cez AJAX sa zisťuje prítomnosťou hlavičky X-Requested-With, ktorú knižnica jQuery automaticky pridáva do každej AJAXovej požiadavky. Táto kontrola sa vykonáva v metóde preDispatch() (Kód 2.3) kontroléra AdminController. To, že je táto metóda volaná pri každom prístupe k danému kontroléru zabezpečuje ZF.
public function preDispatch()
{
$this->_sessions = Zend_Registry::get('sessions');
$action = $this->getRequest()->getActionName();
if(!$this->_sessions->logged && $action != 'login') {
$this->_redirect('admin/login', array('exit' => true));
} else if($this->_sessions->logged && $action == 'login') {
$this->_redirect('admin/index', array('exit' => true));
} else if($action != 'login' && $action != 'index') {
$http = new Zend_Controller_Request_Http();
if($action != 'logout' && !$http->isXmlHttpRequest()) {
$this->_redirect('admin/index', array('exit' => true));
}
}
$this->view->addHelperPath('./application/views/helpers', 'Views_Helpers');
}
Akcie vykonané po prihlásení
Po úspešnom prihlásení sa vykoná synchronizácia tabuľky eval_users s tabuľkou používanou v systéme evalvácie FM. Keďže prístup z iného serveru do databázy, v ktorej sa originálna tabuľka nachádza, nie je z bezpečnostných dôvodov povolený, musel som vytvoriť skript, ktorý vytvorí export[1] potrebných údajov a umiestniť ho na server, na ktorom táto databáza beží. Keďže tento export neobsahuje žiadne citlivé informácie, prístup k nemu nie je nijak zabezpečený a je teda verejne prístupný. Po načítaní exportu tieto údaje porovnávam s údajmi uloženými v lokálnej tabuľke eval_users a v prípade potreby ich aktualizujem, pridávam alebo odoberám záznamy.
Následne kontrolujem aktuálnosť uloženej verzie rozvrhu. V prípade, že sa používateľ do systému prihlási prvýkrát v novom semestri alebo školskom roku, vytvorí sa nový záznam v archíve aplikácie, do ktorého sa uloží aktuálny stav všetkých tabuliek v databáze a záznamy v tabuľkách rozvrh_subjectitems, rozvrh_timetable a rozvrh_timetable_extern sa vymažú. Tabuľka rozvrh_subjectitems sa naplní údajmi z naposledy uloženého záznamu v archíve z príslušného semestra. Fungovaniu archívu sa budem bližšie venovať v časti 4.1.4.
Po vykonaní synchronizácie je používateľ presmerovaný do administrátorskej časti aplikácie. Hneď po vstupe sa zobrazí dialógové okno s hláseniami o výsledku synchronizácie, o stave, v akom sa rozvrh nachádza, a o prípadnom automatickom uložení záznamu do archívu. Hlásenie o výsledku synchronizácie obsahuje zoznam pridaných a zmazaných pedagógoch. Pri nových pedagógoch je používateľovi ponúknutá možnosť doplniť im údaje do tabuľky rozvrh_userdetails, pričom skratka vyučujúceho je povinný údaj. Bez jej určenia všetkým novým pedagógom nie je možné dialógové okno zatvoriť a pokračovať tak v práci s aplikáciou. Hlásenie o stave rozvrhu bližšie opíšem v kapitole 4.1.6.
Po zatvorení dialógového okna s hláseniami môže používateľ pracovať s aplikáciou. Pre vykreslenie ovládacích prvkov prostredia potrebujem z databázy vybrať viaceré údaje: študijné kombinácie a krúžky, informácie o miestnostiach, typoch predmetov, názvy predmetov a vyučujúcich priradených k predmetom, zoznam hodín zaradených do rozvrhu, zoznam hodín nezaradených do rozvrhu a informácie o vyučujúcich. Tieto údaje vyberám v triede adminIndex. Na prácu s databázou používam ZF triedu Zend_Db a po vybratí údajov ich triedim a ukladám do poľa kvôli ľahšej práci s nimi.
public function gAddedSubjects()
{
$select = $this->_db->select()
->from(array('tt' => T_TTABLE),
array('id', 'provides', 'week', 'day', 'hour', 'note', 'room' => 'rozvrh_room_id'))
->join(array('si' => T_SUBITEMS),
'tt.rozvrh_subjectItem_id = si.id',
array('hours', 'subject' => 'rozvrh_subject_id', 'type' => 'rozvrh_subjectType_id', 'subclass' => 'rozvrh_subclass_id'))
->joinLeft(array('t' => T_TEACH),
'tt.rozvrh_teacher_id = t.id',
array('teacher' => 'eval_user_id'))
->join(array('s' => T_SUB),
'si.rozvrh_subject_id = s.id',
array('comb' => 'rozvrh_combination_id'));
$result = $this->_db->fetchAll($select);
$return = array();
foreach($result as $row) {
if(!isset($return[$row['room']][$row['day']][$row['week']][$row['hour']])) {
$return[$row['room']][$row['day']][$row['week']][$row['hour']] =
array(
'provides' => $row['provides'],
'hours' => $row['hours'],
'teacher' => $row['teacher'],
'subject' => $row['subject'],
'comb' => $row['comb'],
'type' => $row['type'],
'note' => $row['note'],
'subclasses' => array()
);
}
$return[$row['room']][$row['day']][$row['week']][$row['hour']]['subclasses'][$row['subclass']] = $row['id'];
}
return $return;
}
T_TTABLE, T_SUBITEMS, T_TEACH a T_SUB sú konštanty reprezentujúce názvy tabuliek v databáze. Tieto konštanty sú definované v samostatnom súbore tables.php, ktorý sa nachádza v konfiguračnom priečinku aplikácie.
- T_TTABLE – rozvrh_timetable
- T_SUBITEMS – rozvrh_subjectitems
- T_TEACH – rozvrh_teachers
- T_SUB – rozvrh_subjects
$this->_db je objekt triedy Zend_Db. Táto trieda obsahuje metódy pre prácu s databázou. Zoznam niektorých metód a ich význam:
- select() – vytvára objekt triedy Zend_Db_Select pre vytvorenie dopytu na databázu typu SELECT
- from($table, $columns) – FROM časť dopytu
- $table – názov tabuľky. Môže byť typu reťazec alebo pole. V prípade typu pole kľúč označuje alias tabuľky a hodnota názov tabuľky
- $columns – zoznam stĺpcov, ktoré sa majú vybrať. Môže byť typu reťazec alebo pole. V prípade poľa môže ísť o asociatívne alebo číselné pole. Ak je pole asociatívne, kľúč znamená alias stĺpca
- join($table, $condition, $columns), joinLeft($table, $condition, $columns) – INNER JOIN, JOIN LEFT časť dopytu
- $table – ako vo from()
- $condition – podmienka spájania výsledkov
- $columns – ako vo from()
- fetchAll($select) – metóda, ktorá vracia všetky záznamy vrátené databázou. Formát vrátených údajov sa dá nastaviť metódou setFetchMode(). Prednastavený formát je asociatívne pole
- $select – dopyt, ktorý sa má vykonať. Môže byť typu reťazec alebo objekt triedy Zend_Db_Select
Po vybratí údajov z databázy sa výsledky prechádzajú v cykle foreach a ukladajú sa do poľa $return (Kód 2.5) v novom poradí.
array(
T_TTABLE.rozvrh_room_id => array(
T_TTABLE.day => array(
T_TTABLE.week => array(
T_TTABLE.hour => array(
'provides' => T_TTABLE.provides,
'hours' => T_SUBITEMS.hours,
'teacher' => T_TEACH.eval_user_id,
'type' => T_SUBITEMS.rozvrh_subjectType_id,
'note' => T_TTABLE.note,
'data' => array(
T_SUB.rozvrh_combination_id => array(
'subject' => T_SUBITEMS.rozvrh_subject_id,
'subclasses' => array(
T_SUBITEMS.rozvrh_subclass_id => T_TTABLE.id
)
)
)
)
)
)
)
Tieto mnohorozmerné polia posúvam v kontroléri do skriptu, ktorý sa stará o vykresľovanie stránky. V skripte následne postupným prechádzaním polí vytváram jednotlivé ovládacie prvky.
Keďže na vykreslenie niektorých prvkov využívam JavaScript, musím tieto polia s údajmi vložiť aj do jeho zdrojového kódu (Kód 2.6). Na túto úlohu používam JSON[2], formát pre prenos dát z jedného programovacieho jazyka do druhého. Premenná akéhokoľvek typu zakódovaná do formátu JSON je reťazec s pevne danou štruktúrou, z ktorého vie prijímajúci jazyk vytvoriť premennú rovnakého typu. Ak požadovaný typ v jazyku neexistuje, použije sa ekvivalentný typ s vlastnosťami čo najviac podobnými pôvodnému typu.
<script type="text/javascript">
var subjects_added = eval(<?php echo json_encode($this->sub_added);?>);
</script>
Grafický návrh administrátorského prostredia
Pri návrhu používateľského rozhrania som kládol dôraz na komfort, prehľadnosť a intuitívnosť ovládania. Snažil som sa o používanie grafických prvkov a implementovanie funkcionalít, na ktoré sú používatelia počítača a internetových aplikácií zvyknutí a očakávajú ich, napr. presúvanie objektov, mazanie objektu stlačením klávesy Delete, zobrazenie dodatočných informácií o objekte pri presunutí kurzoru nad daný objekt atď. Na zabezpečenie takýchto funkcií sa na internetových stránkach používa JavaScript. Keďže je mnou navrhované prostredie pomerne dynamické, potrebuje veľké množstvo JavaScriptového kódu, čo by sa mohlo prejaviť na plynulosti behu aplikácie. Preto program testujem na posledných verziách všetkých majoritných internetových prehliadačoch: Firefox, Opera, Internet Explorer a Chrome. K zrýchleniu behu JavaScriptového kódu pomáha tiež použitie knižnice jQuery, ktorá je výborne optimalizovaná.
Ďalším problémom, ktorý pri použití JavaScriptu môže nastať, je, že v prípade, že ho má používateľ vypnutý, sa aplikácia stane nepoužiteľnou. Bežným zvykom pri tvorbe internetových stránok je preto snaha písať kód stránky tak, aby bola zabezpečená aspoň jej základná funkčnosť aj pri vypnutom JavaScripte. Avšak keďže náš systém budú používať iba tvorcovia rozvrhu, ktorí budú o nutnosti mať zapnutý JavaScript upozornení, nebudem tieto opatrenia do kódu stránky vkladať.
Na Obr. 2.2 je znázornená podoba systému v normálnom stave. Pri akciách, ktoré potrebujú získať dodatočné vstupy od používateľa alebo zobraziť dodatočné informácie, sa na tento účel zobrazí na obrazovke dialógové okno, ktoré môže mať systémovo-modálny charakter, tzn. okno bude nad ostatnými prvkami a ostatné prvky stránky sa stanú neaktívnymi až do zatvorenia dialógového okna.
Vo vrchnej časti stránky sa nachádza hlavné menu (Obr. 2.3). Jedná sa o tzv. drop-down menu – viacúrovňové menu ovládané pomocou JavaScriptu, ktorého ďalšia úroveň sa zobrazí po prechode kurzoru nad nadradenou úrovňou a skryje sa po odchode myši z nadradenej úrovne.
Položky menu obsahujú odkazy na všetky potrebné funkcie aplikácie, napr.: práca s archívom rozvrhu, správa krúžkov, správa vyučujúcich atď. Pre vytvorenie a prácu s hlavným menu som vytvoril triedu My_MainMenu, ktorej konštruktor prijíma ako parameter mnohorozmerné pole s presne určenou štruktúrou (Kód 2.7), ktoré reprezentuje dané menu.
array(
array(
‘label’ => ‘Rozvrh’,
‘js’ => ‘rozvrh’[,
[‘title’ => ‘Správa rozvrhu’,]
[‘img’ => ‘yes.gif’,]
[‘style’ => ‘float:right;’,]
[‘sub’ => array(...)]]
)
[, array(...)]
);
V nasledujúcom texte je opis štruktúry, ktorá je použitá ako parameter konštruktora triedy My_MainMenu.
- label – zobrazovaný text položky menu
- js – identifikátor položky menu pre JavaScript. Identifikátory nižších úrovní menu sa reťazia s použitím oddeľovača –
- title (nepovinné) – text, ktorý sa zobrazí ako nápoveda pri prechode myši nad prvkom. Ak tento atribút nie je zadaný, použije sa ako text nápovedy hodnota atribútu label
- img (nepovinné) – obrázok, ktorý sa vloží pred text položky
- style (nepovinné) – CSS vlastnosti danej položky. Tento atribút som pridal hlavne kvôli položke Odhlásiť sa, ktorá je od ostatných položiek opticky oddelená
- sub (nepovinné) – zoznam položiek nižšej úrovne
Zoznam hodín zaradených do rozvrhu
Zoznam hodín zaradených do rozvrhu (Obr. 2.4) je tvorený tabuľkou, ktorá obsahuje všetky vyučovacie hodiny s určeným časom a učebňou. Stĺpec tabuľky určuje hodinu, riadok učebňu, v ktorej sa výučba koná. Každý riadok učebne je rozdelený na dve časti, horná časť znamená párny týždeň, spodná časť nepárny. Ak sa výučba opakuje každý týždeň, hodina presahuje obe polovice.
Nad tabuľkou sa nachádzajú záložky na zmenu dňa, pre ktorý sa bude tvoriť rozvrh. Pre každý deň je vytvorená samostatná tabuľka, pričom je zobrazená vždy len tabuľka prislúchajúca k aktuálne vybratému dňu. Odkazom v záložke napravo sa prepína do správy rozvrhu externých študentov, ktorá má iné prostredie.
Bližší popis buniek s jednotlivými hodinami uvediem v kapitole 4.1.3.
Zoznam hodín nezaradených do rozvrhu
Zoznam hodín nezaradených do rozvrhu (Obr. 2.5) obsahuje bloky vyučovacích hodín, ktoré boli do systému pridané, ale ešte nebola určená ich hodina a miestnosť výučby. Pri vstupe do administrátorského prostredia sa nachádza v ľavom dolnom rohu obrazovky. Jeho pozícia je daná fixne, to znamená, že pri rolovaní stránky zostáva zoznam na mieste. Dá sa však presúvať uchopením za hornú časť alebo tiež dvojklikom kdekoľvek na stránku – zoznam sa presunie do danej výšky.
V spodnej časti sa nachádza zoznam študijných odborov a ich ročníkov. Farba položiek korešponduje s farebným označením buniek v tabuľke hodín zaradených do rozvrhu. V hornej časti sa nachádza zoznam predmetov, ktoré sú k vybranému odboru a ročníku pridelené. Jednotlivé predmety sú tvorené systémom záložiek podobne ako prepínanie dní.
Kvôli veľkosti zoznamu som sa rozhodol pridať mu funkciu minimalizácie a maximalizácie, takže po vybratí predmetu sa zobrazí stredná časť (Obr. 2.6), v ktorej sa nachádzajú jednotlivé nezaradené hodiny. Naľavo sú typy predmetov, napravo je zoznam krúžkov vo zvolenom odbore a ročníku. Tieto prvky sú taktiež tvorené systémom záložiek, aj keď pri nich som na rozdiel od ostatných záložiek nemohol použiť hotový systém z knižnice jQuery UI kvôli ich vertikálnej polohe. V prípade, že sa vyberie typ predmetu prednáška, zoznam krúžkov sa skryje, pretože prednášky sa pridávajú pre všetky krúžky naraz. Medzi typmi predmetov a krúžkami sa nachádzajú jednotlivé nepriradené predmety rozdelené podľa dĺžky výučby.