Návrh systému rozvrhu pre FM TnU AD: Rozdiel medzi revíziami

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
d
 
(13 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených)
Riadok 4: Riadok 4:
 
[[Kategória:web]]
 
[[Kategória:web]]
 
[[Kategória:php]]
 
[[Kategória:php]]
<H1_CSS chapter="2" prefix="Kapitola" />
 
<div class="sideBox">
 
{| class="" border=0 cellpadding=5
 
|+ Obsah práce
 
|-
 
| 1.
 
| [[Systém tvorby rozvrhu|Popis systémov pre tvorbu rozvrhu]]
 
|-
 
| 2.
 
| [[Systém tvorby rozvrhu_2|Rozvrh pre FM TnU AD]]
 
|-
 
| 3
 
| [[Systém tvorby rozvrhu_3|Záver]]
 
|}
 
</div>
 
  
 +
{{Praca_uvod|2|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__
 +
 +
= =
 +
 +
Systémy pre tvorbu rozvrhu sa, tak ako väčšina aplikácií, v ktorých sú určené úlohy používateľov na základe rozličných stupňov oprávnení, delia na používateľskú a administrátorskú časť. Mojou úlohou bolo vytvoriť administrátorské prostredie aplikácie na správu rozvrhu pre potreby Fakulty mechatroniky TnUAD.  Preto sa ďalej v práci budem zaoberať iba touto stránkou aplikácie a používateľské prostredie spomeniem iba v súvislosti
 +
s funkciami administrátorského prostredia. Aplikácia dostala názov rozvrhFM.
 +
 +
== Použité programovacie prostriedky ==
 +
Jednou z požiadaviek pri zadaní úlohy bolo,  aby bola  aplikácia online  kvôli možnosti jednoducho pristupovať k nej z akéhokoľvek počítača.  Rozhodol som sa preto vytvoriť klasickú internetovú aplikáciu pomocou jazykov HTML a JavaScript, na strane servera potom PHP,  čo  je v súčasnosti najpoužívanejší  serverový skriptovací jazyk.  Na ukladanie údajov používam databázu MySQL. Všetky akcie vykonané administrátorom sa prenášajú na server pomocou technológie AJAX, čo eliminuje potrebu opätovného načítavania stránky a zrýchľuje tak prácu s aplikáciou rovnako ako záťaž na server.
 +
 +
=== HTML ===
  
=Rozvrh pre FM TnU AD=
 
V súčasnosti sa rozvrh pre FM TnU AD tvorí pomocou aplikácie MS Excel a následne sa údaje ručne vkladajú do databázy pre zobrazenie na internetovej stránke fakulty. Takéto riešenie je však krajne nepohodlné. Nielen že vkladanie množstva údajov do databázy je prácne, ale pri každej následnej zmene v rozvrhu treba údaje vyhľadávať a editovať. Okrem toho MS Excel nie je aplikácia priamo určená na tvorbu rozvrhu, preto mu chýbajú viaceré funkcie, ktoré by mal takýto program mať a treba pri práci s ním robiť viaceré kompromisy. Preto je súčasťou mojej práce vytvoriť návrh a následne aj naprogramovanie online aplikácie pre tvorbu rozvrhu našej fakulty. Zameriavam sa pritom na administrátorské prostredie aplikácie.
 
==Prípravné práce==
 
Ako som už naznačil v podkapitole [[Systém_tvorby_rozvrhu#Hlavn.C3.A9_parametre_syst.C3.A9mu|1.1]], je dobrým zvykom každého programátora si pred vlastným programovaním premyslieť niektoré parametre aplikácie, ktoré chce dosiahnuť. Preto aj ja venujem túto podkapitolu teoretickej príprave a premysleniu schopností a parametrov, ktoré by mal program mať.
 
===Použité programovacie prostriedky===
 
Jednou z požiadaviek pri zadaní úlohy bolo, že ma byť aplikácia online kvôli možnosti jednoducho pristupovať k nej z akéhokoľvek počítača. Rozhodol som sa preto vytvoriť klasickú internetovú aplikáciu pomocou jazykov HTML a JavaScript, na strane serveru potom PHP, ktorý je v súčasnosti najpoužívanejší serverový skriptovací jazyk.  Na ukladanie údajov používam databázu MySQL. V maximálnej miere využívam technológiu AJAX.
 
====HTML====
 
 
HTML<ref>http://sk.wikipedia.org/wiki/Hypertext_markup_language</ref> je značkový jazyk určený na vytváranie webových stránok a iných informácií zobraziteľných vo webovom prehliadači. HTML kladie dôraz skôr na prezentáciu informácií (odseky, fonty, váha písma, tabuľky atď.) ako na sémantiku (význam slov). Pôvodne bol určený ako veľmi zjednodušená podmnožina jazyka SGML, ktorý sa používa v organizáciách s komplexnými publikačnými požiadavkami, ale neskôr sa stal samostatným štandardom (ISO/IEC 15445:2000). Špecifikáciu jazyka HTML udržiava World Wide Web Consortium (W3C)<ref>http://www.w3.org/</ref>.
 
HTML<ref>http://sk.wikipedia.org/wiki/Hypertext_markup_language</ref> je značkový jazyk určený na vytváranie webových stránok a iných informácií zobraziteľných vo webovom prehliadači. HTML kladie dôraz skôr na prezentáciu informácií (odseky, fonty, váha písma, tabuľky atď.) ako na sémantiku (význam slov). Pôvodne bol určený ako veľmi zjednodušená podmnožina jazyka SGML, ktorý sa používa v organizáciách s komplexnými publikačnými požiadavkami, ale neskôr sa stal samostatným štandardom (ISO/IEC 15445:2000). Špecifikáciu jazyka HTML udržiava World Wide Web Consortium (W3C)<ref>http://www.w3.org/</ref>.
====JavaScript====
+
 
 +
Vo svojej aplikácií používam poslednú verziu, ktorou je HTML 4.01.
 +
 
 +
=== JavaScript ===
 +
 
 
JavaScript<ref>http://sk.wikipedia.org/wiki/JavaScript</ref> je skriptovací programovací jazyk používaný najmä pri tvorbe webových stránok. Pôvodne ho vyvíjal Brendan Eich zo spoločnosti Netscape Communications pod názvom Mocha, neskôr pod menom LiveScript. Pred uvedením na verejnosť bol premenovaný na JavaScript, najmä pre vtedajšiu popularitu jazyka Java.
 
JavaScript<ref>http://sk.wikipedia.org/wiki/JavaScript</ref> je skriptovací programovací jazyk používaný najmä pri tvorbe webových stránok. Pôvodne ho vyvíjal Brendan Eich zo spoločnosti Netscape Communications pod názvom Mocha, neskôr pod menom LiveScript. Pred uvedením na verejnosť bol premenovaný na JavaScript, najmä pre vtedajšiu popularitu jazyka Java.
  
 
Pre uľahčenie práce s JavaScriptom som sa rozhodol vo svojej aplikácií použiť knižnicu jQuery<ref>http://jquery.com/</ref> a jej nadstavbu jQuery UI. jQuery je JavaScriptová knižnica, ktorá zjednocuje funkcie pre rôzne prehliadače, skracuje a zjednodušuje syntax, ponúka funkcie pre prácu s AJAXom a na animácie prvkov internetovej stránky. Jej nadstavba jQuery UI ďalej rozširuje tieto možnosti a ponúka kompletné riešenia najpoužívanejších užívateľských prvkov, napr.: dialógové okná, prepínacie záložky, kalendár, vysúvacie menu atď.
 
Pre uľahčenie práce s JavaScriptom som sa rozhodol vo svojej aplikácií použiť knižnicu jQuery<ref>http://jquery.com/</ref> a jej nadstavbu jQuery UI. jQuery je JavaScriptová knižnica, ktorá zjednocuje funkcie pre rôzne prehliadače, skracuje a zjednodušuje syntax, ponúka funkcie pre prácu s AJAXom a na animácie prvkov internetovej stránky. Jej nadstavba jQuery UI ďalej rozširuje tieto možnosti a ponúka kompletné riešenia najpoužívanejších užívateľských prvkov, napr.: dialógové okná, prepínacie záložky, kalendár, vysúvacie menu atď.
====PHP====
+
 
 +
=== PHP ===
 +
 
 
PHP<ref>http://php.net/</ref> je populárny open source skriptovací programovací jazyk, ktorý sa používa najmä na programovanie klient-server aplikácií (na strane servera) a pre vývoj dynamických webových stránok.
 
PHP<ref>http://php.net/</ref> je populárny open source skriptovací programovací jazyk, ktorý sa používa najmä na programovanie klient-server aplikácií (na strane servera) a pre vývoj dynamických webových stránok.
  
Pre PHP taktiež existujú viaceré knižnice. Ja som si pre svoju aplikáciu vybral knižnicu Zend Framework vyvíjanú spoločnosťou Zend Technologies<ref>http://framework.zend.com/</ref>, ktorá sa taktiež podieľa na vývoji PHP. Ide o plne objektovo orientovanú knižnicu zjednodušujúcu mnohé úlohy od práce s databázou po integráciu so službami iných poskytovateľov, napríklad Google. Zend Framework podporuje a tiež odporúča oddelenie zobrazovania obsahu od vykonávania logiky programu, tzv. MVC (Model-View-Controller) model.
+
Pre PHP taktiež existujú viaceré knižnice. Ja som si pre svoju aplikáciu vybral knižnicu Zend Framework vyvíjanú spoločnosťou Zend Technologies<ref>http://framework.zend.com/</ref>, ktorá sa taktiež podieľa na vývoji PHP. Ide o plne objektovo orientovanú knižnicu zjednodušujúcu mnohé úlohy od práce s databázou po integráciu so službami iných poskytovateľov, napríklad Google. Zend Framework podporuje a tiež odporúča oddelenie zobrazovania obsahu od vykonávania logiky programu, tzv. MVC (Model-View-Controller) model. Ďalej v práci budem používať niektoré výrazy z terminológie MVC:
====AJAX====
+
*Model  –  časť aplikácie, ktorá definuje jej základnú funkcionalitu pomocou skupiny abstrakcií. Môžu v ňom byť definované rutiny prístupu k dátam a základná logika programu.
 +
*View  –  presne definuje to, čo je prezentované používateľovi.  Obyčajne kontrolér posúva dáta každému view, aby ich zobrazil v požadovanom formáte. View často zbiera údaje od používateľa. Sem sa vkladajú HTML značky.
 +
*Controller (Kontrolér) – spája celý model dohromady. Narába s modelmi, rozhoduje, ktorý model sa má zobraziť, na základe požiadavky od používateľa a ostatných faktoroch, zbiera dáta, ktoré bude view potrebovať a posúva  mu ich alebo predáva kontrolu inému kontroléru.
 +
 
 +
=== AJAX ===
 +
 
 
AJAX<ref>http://www.w3schools.com/Ajax/Default.Asp</ref> prakticky nie je programovací jazyk. Je to kombinácia asynchrónneho JavaScriptu a serverového skriptovacieho jazyka. Používa sa na vývoj interaktívnych webových aplikácií, ktoré menia obsah svojich stránok bez nutnosti ich opätovného načítania.
 
AJAX<ref>http://www.w3schools.com/Ajax/Default.Asp</ref> prakticky nie je programovací jazyk. Je to kombinácia asynchrónneho JavaScriptu a serverového skriptovacieho jazyka. Používa sa na vývoj interaktívnych webových aplikácií, ktoré menia obsah svojich stránok bez nutnosti ich opätovného načítania.
====MySQL====
+
=== MySQL ===
 
MySQL<ref>http://www.mysql.com/</ref> je slobodný a otvorený viacvláknový, viacužívateľský SQL relačný databázový server v súčasnosti vlastnený spoločnosťou Sun Microsystems. Je podporovaný na viacerých platformách a je implementovaný vo viacerých programovacích jazykoch ako PHP, C++ či Perl. Databázový systém je relačný typu DBMS. Každá databáza je v MySQL tvorená z jednej alebo z viacerých tabuliek, ktoré majú riadky a stĺpce. V riadkoch sa rozoznávajú jednotlivé záznamy, stĺpce udávajú dátový typ jednotlivých záznamov, pracuje sa s nimi ako s poľami. Práca s MySQL databázou je vykonávaná pomocou takzvaných dotazov, ktoré vychádzajú z programovacieho jazyka.
 
MySQL<ref>http://www.mysql.com/</ref> je slobodný a otvorený viacvláknový, viacužívateľský SQL relačný databázový server v súčasnosti vlastnený spoločnosťou Sun Microsystems. Je podporovaný na viacerých platformách a je implementovaný vo viacerých programovacích jazykoch ako PHP, C++ či Perl. Databázový systém je relačný typu DBMS. Každá databáza je v MySQL tvorená z jednej alebo z viacerých tabuliek, ktoré majú riadky a stĺpce. V riadkoch sa rozoznávajú jednotlivé záznamy, stĺpce udávajú dátový typ jednotlivých záznamov, pracuje sa s nimi ako s poľami. Práca s MySQL databázou je vykonávaná pomocou takzvaných dotazov, ktoré vychádzajú z programovacieho jazyka.
===Databáza===
+
 
 +
== Návrh databázovej štruktúry systému rozvrhFM ==
 +
 
 
Jednou z hlavných prípravných úloh pri vytváraní internetovej aplikácie je návrh databázovej štruktúry. Hlavne pri zložitejších aplikáciách, ktoré uchovávajú v databáze veľké množstvo dát, je návrh databázovej štruktúry kľúčovou otázkou. Správny návrh totižto môže uľahčiť vytváranie dotazov na databázu, zjednodušiť zdrojový kód aplikácie, zmenšiť miesto zaberané údajmi databázy na minimum a v neposlednom rade zmenšiť záťaž na server a tým zabezpečiť rýchly a bezchybný chod aplikácie.
 
Jednou z hlavných prípravných úloh pri vytváraní internetovej aplikácie je návrh databázovej štruktúry. Hlavne pri zložitejších aplikáciách, ktoré uchovávajú v databáze veľké množstvo dát, je návrh databázovej štruktúry kľúčovou otázkou. Správny návrh totižto môže uľahčiť vytváranie dotazov na databázu, zjednodušiť zdrojový kód aplikácie, zmenšiť miesto zaberané údajmi databázy na minimum a v neposlednom rade zmenšiť záťaž na server a tým zabezpečiť rýchly a bezchybný chod aplikácie.
  
Riadok 64: Riadok 67:
 
</ol>
 
</ol>
 
Jedinou výnimkou z pravidiel a) a b) je tabuľka eval_user, pretože sa plánovalo, že sa použije už existujúca tabuľka, ktorá sa používa v iných aplikáciách fakulty. Neskôr sa však ukázalo, že aplikácia bude bežať na inom servery, než sa nachádza existujúca tabuľka eval_users. Síce by sa dali používať v aplikácií údaje z tejto vzdialenej databázy, ale nebolo by tak možné plne využiť potenciál použitého úložného systému InnoDB, ktorý nedokáže vytvárať závislosti medzi tabuľkami z rozdielnych serverov. Rozhodol som sa teda vytvoriť kópiu tejto tabuľky v databáze našej aplikácie, ale kvôli nutnosti prepisovať už vytvorený kód som nepristúpil k premenovaniu tabuľky a cudzích kľúčov.
 
Jedinou výnimkou z pravidiel a) a b) je tabuľka eval_user, pretože sa plánovalo, že sa použije už existujúca tabuľka, ktorá sa používa v iných aplikáciách fakulty. Neskôr sa však ukázalo, že aplikácia bude bežať na inom servery, než sa nachádza existujúca tabuľka eval_users. Síce by sa dali používať v aplikácií údaje z tejto vzdialenej databázy, ale nebolo by tak možné plne využiť potenciál použitého úložného systému InnoDB, ktorý nedokáže vytvárať závislosti medzi tabuľkami z rozdielnych serverov. Rozhodol som sa teda vytvoriť kópiu tejto tabuľky v databáze našej aplikácie, ale kvôli nutnosti prepisovať už vytvorený kód som nepristúpil k premenovaniu tabuľky a cudzích kľúčov.
[[Súbor:mpbc1.5.png|thumbnail|center|800px|Obr. 2.1 Zvolená štruktúra tabuliek v databáze]]
+
[[Súbor:mpbc1.5.png|thumbnail|center|700px|Obr. 2.1 Zvolená štruktúra tabuliek v databáze]]
 
Nasleduje podrobný popis jednotlivých tabuliek a vzťahov medzi nimi.
 
Nasleduje podrobný popis jednotlivých tabuliek a vzťahov medzi nimi.
=====Tabuľka rozvrh_restrictions=====
+
 
 +
'''Tabuľka rozvrh_restrictions'''
 +
 
 
Obmedzenia vyučujúcich. Zoznam hodín, v ktoré vyučujúci nemôže učiť.
 
Obmedzenia vyučujúcich. Zoznam hodín, v ktoré vyučujúci nemôže učiť.
 
{|border="1" cellspacing="0" cellpadding="5" align="center" width="500px"
 
{|border="1" cellspacing="0" cellpadding="5" align="center" width="500px"
Riadok 73: Riadok 78:
 
|-
 
|-
 
|week||ENUM('k','p','n')||týždeň obmedzenia pedagóga||k – každý<br>p – párny<br>n - nepárny
 
|week||ENUM('k','p','n')||týždeň obmedzenia pedagóga||k – každý<br>p – párny<br>n - nepárny
 +
|-
 +
|day||INT(1)||číslo dňa||1 – pondelok<br>...<br>6 - sobota
 
|-
 
|-
 
|hour||TINYINT(2)||časový slot 1 hodina||8 - 20
 
|hour||TINYINT(2)||časový slot 1 hodina||8 - 20
Riadok 83: Riadok 90:
 
|eval_user_id||eval_users||1:n||nie
 
|eval_user_id||eval_users||1:n||nie
 
|}
 
|}
=====Tabuľka eval_users=====
+
 
 +
'''Tabuľka eval_users'''
 +
 
 
Kópia vybratých stĺpcov tabuľky použitej v systéme evalvácie fakulty. Táto tabuľka sa nachádza v inej databáze a na inom serveri. V tabuľke sú informácie o pedagógoch na FM.
 
Kópia vybratých stĺpcov tabuľky použitej v systéme evalvácie fakulty. Táto tabuľka sa nachádza v inej databáze a na inom serveri. V tabuľke sú informácie o pedagógoch na FM.
 
{|border="1" cellspacing="0" cellpadding="5" align="center" width="500px"
 
{|border="1" cellspacing="0" cellpadding="5" align="center" width="500px"
Riadok 97: Riadok 106:
 
|email||VARCHAR(32)||email osoby||&nbsp;
 
|email||VARCHAR(32)||email osoby||&nbsp;
 
|}
 
|}
=====Tabuľka rozvrh_teachers=====
+
 
 +
'''Tabuľka rozvrh_teachers'''
 +
 
 
Priradenie vyučujúceho k danému predmetu. K jednému predmetu môže byť priradených viacero vyučujúcich rovnako ako jeden vyučujúci môže byť priradený k viacerým predmetom. Táto tabuľka vznikla pri rozdelení vzťahu n:m medzi tabuľkami rozvrh_subjects a eval_users na dva vzťahy 1:n
 
Priradenie vyučujúceho k danému predmetu. K jednému predmetu môže byť priradených viacero vyučujúcich rovnako ako jeden vyučujúci môže byť priradený k viacerým predmetom. Táto tabuľka vznikla pri rozdelení vzťahu n:m medzi tabuľkami rozvrh_subjects a eval_users na dva vzťahy 1:n
  
Riadok 116: Riadok 127:
 
|}
 
|}
  
=====Tabuľka rozvrh_userdetails=====
+
'''Tabuľka rozvrh_userdetails'''
 +
 
 
Doplňujúce informácie o zamestnancovi. Tieto informácie nie sú relevantné v systéme evalvácie FM, preto je vytvorená táto tabuľka.
 
Doplňujúce informácie o zamestnancovi. Tieto informácie nie sú relevantné v systéme evalvácie FM, preto je vytvorená táto tabuľka.
  
Riadok 134: Riadok 146:
 
|eval_user_id||eval_users||1:n||nie
 
|eval_user_id||eval_users||1:n||nie
 
|}
 
|}
=====Tabuľka rozvrh_combinations=====
+
 
 +
'''Tabuľka rozvrh_combinations'''
 +
 
 
Študijné kombinácie na FM.
 
Študijné kombinácie na FM.
  
Riadok 146: Riadok 160:
 
|-
 
|-
 
|year||TINYINT(1)||ročník||1 - 5
 
|year||TINYINT(1)||ročník||1 - 5
 +
|-
 +
|color||VARCHAR(7)||farebné označenie||#RRGGBB
 
|}
 
|}
=====Tabuľka rozvrh_subjects=====
+
 
 +
'''Tabuľka rozvrh_subjects'''
 +
 
 
Zoznam predmetov. V tabuľke nie je informácia o type predmetu ani o dĺžke trvania predmetu.
 
Zoznam predmetov. V tabuľke nie je informácia o type predmetu ani o dĺžke trvania predmetu.
  
Riadok 167: Riadok 185:
 
|rozvrh_combination_id||rozvrh_combination||1:n||nie
 
|rozvrh_combination_id||rozvrh_combination||1:n||nie
 
|}
 
|}
=====Tabuľka rozvrh_subclasses=====
+
 
 +
'''Tabuľka rozvrh_subclasses'''
 +
 
 
Zoznam krúžkov. Krúžky sú označené len dvojčíslom, ktoré tvorí poslednú časť názvu krúžku. Prvé tri číslice skutočného názvu krúžku predstavujú fakultu, zameranie a ročník.
 
Zoznam krúžkov. Krúžky sú označené len dvojčíslom, ktoré tvorí poslednú časť názvu krúžku. Prvé tri číslice skutočného názvu krúžku predstavujú fakultu, zameranie a ročník.
  
Riadok 175: Riadok 195:
 
|-
 
|-
 
|sign||VARCHAR(2)||označenie krúžkov||01, 02 ... – denní študenti<br>E – externí študenti
 
|sign||VARCHAR(2)||označenie krúžkov||01, 02 ... – denní študenti<br>E – externí študenti
 +
|-
 +
|note||VARCHAR(300)||poznámka||
 
|}<br>
 
|}<br>
  
Riadok 183: Riadok 205:
 
|rozvrh_combination_id||rozvrh_combination||1:n||nie
 
|rozvrh_combination_id||rozvrh_combination||1:n||nie
 
|}
 
|}
=====Tabuľka rozvrh_subjecttypes=====
+
 
 +
'''Tabuľka rozvrh_subjecttypes'''
 +
 
 
Typy vyučovacích hodín.
 
Typy vyučovacích hodín.
  
Riadok 195: Riadok 219:
 
|}
 
|}
  
=====Tabuľka rozvrh_subjectitems=====
+
'''Tabuľka rozvrh_subjectitems'''
 +
 
 
Prepojovacia tabuľka, prepojuje predmet s typom predmetu a krúžkom
 
Prepojovacia tabuľka, prepojuje predmet s typom predmetu a krúžkom
  
Riadok 215: Riadok 240:
 
|rozvrh_subclass_id||rozvrh_subclasses||1:n||áno, ak majú všetky krúžky hodinu spoločne
 
|rozvrh_subclass_id||rozvrh_subclasses||1:n||áno, ak majú všetky krúžky hodinu spoločne
 
|}
 
|}
=====Tabuľka rozvrh_rooms=====
+
 
 +
'''Tabuľka rozvrh_rooms'''
 +
 
 
Zoznam učební a ich vlastnosti.
 
Zoznam učební a ich vlastnosti.
  
Riadok 231: Riadok 258:
 
|}
 
|}
  
=====Tabuľka rozvrh_timetable=====
+
'''Tabuľka rozvrh_timetable'''
 +
 
 
Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - denné štúdium
 
Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - denné štúdium
  
Riadok 260: Riadok 288:
 
|}
 
|}
  
=====Tabuľka rozvrh_timetable_extern=====
+
'''Tabuľka rozvrh_timetable_extern'''
 +
 
 
Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - externé štúdium
 
Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - externé štúdium
  
Riadok 291: Riadok 320:
 
|}
 
|}
  
====Pohľady====
+
'''Pohľady'''
 +
 
 
Okrem spomínaných  tabuliek som v databáze vytvoril dve pohľady (views) – rozvrh_view a rozvrh_view_extern. Pohľady sú virtuálne tabuľky - na rozdiel od normálnych tabuliek neobsahujú žiadne údaje, ale iba SQL dopyt, ktorý vyberá z jednej, ale častejšie viacerých tabuliek údaje a spája ich podľa zadaných kritérií. Používajú sa hlavne v prípadoch, že sú spolusúvisiace údaje rozdelené do viacerých tabuliek. Pri výbere z takýchto tabuliek je tvorba dopytov často veľmi komplikovaná, preto je jednoduchšie použiť pohľad. Ďalším prípadom, kedy je vhodné použiť pohľad namiesto prístupu k samotným tabuľkám je, keď viaceré aplikácie zdieľajú tú istú databázu a programátor chce zabrániť niektorým z nich v editácií údajov. Dáta v pohľadoch sú totiž read-only, tzn. určené len na čítanie. Nie je možné cez pohľad údaje do databázy pridávať, meniť ich alebo ich mazať. Na druhú stranu akákoľvek zmena v tabuľkách, z ktorých je pohľad vytvorený, sa okamžite prejaví aj v ňom.
 
Okrem spomínaných  tabuliek som v databáze vytvoril dve pohľady (views) – rozvrh_view a rozvrh_view_extern. Pohľady sú virtuálne tabuľky - na rozdiel od normálnych tabuliek neobsahujú žiadne údaje, ale iba SQL dopyt, ktorý vyberá z jednej, ale častejšie viacerých tabuliek údaje a spája ich podľa zadaných kritérií. Používajú sa hlavne v prípadoch, že sú spolusúvisiace údaje rozdelené do viacerých tabuliek. Pri výbere z takýchto tabuliek je tvorba dopytov často veľmi komplikovaná, preto je jednoduchšie použiť pohľad. Ďalším prípadom, kedy je vhodné použiť pohľad namiesto prístupu k samotným tabuľkám je, keď viaceré aplikácie zdieľajú tú istú databázu a programátor chce zabrániť niektorým z nich v editácií údajov. Dáta v pohľadoch sú totiž read-only, tzn. určené len na čítanie. Nie je možné cez pohľad údaje do databázy pridávať, meniť ich alebo ich mazať. Na druhú stranu akákoľvek zmena v tabuľkách, z ktorých je pohľad vytvorený, sa okamžite prejaví aj v ňom.
  
 
Pohľady v našej databáze obsahujú všetky potrebné informácie o predmete, vyučujúcom, krúžku a čase a mieste konania výučby vo vytvorenom rozvrhu - rozvrh_view v rozvrhu pre denných študentov a rozvrh_view_extern pre externistov. Pohľady budú použité v tých častiach aplikácie, ktoré nepotrebujú práva na editáciu údajov v databáze, tzn. frontend, modul štatistík a exportov a všetky ostatné časti okrem administrátorského prostredia. Oddelenie údajov o rozvrhu pre denných a externých študentov, ako v pohľadoch, tak aj v samotných tabuľkách, bolo pritom nutné kvôli odlišnej relevancií informácií pre oba typy rozvrhov.
 
Pohľady v našej databáze obsahujú všetky potrebné informácie o predmete, vyučujúcom, krúžku a čase a mieste konania výučby vo vytvorenom rozvrhu - rozvrh_view v rozvrhu pre denných študentov a rozvrh_view_extern pre externistov. Pohľady budú použité v tých častiach aplikácie, ktoré nepotrebujú práva na editáciu údajov v databáze, tzn. frontend, modul štatistík a exportov a všetky ostatné časti okrem administrátorského prostredia. Oddelenie údajov o rozvrhu pre denných a externých študentov, ako v pohľadoch, tak aj v samotných tabuľkách, bolo pritom nutné kvôli odlišnej relevancií informácií pre oba typy rozvrhov.
===Bezpečnosť aplikácie===
+
<source lang="sql">
Síce nie je v silách ani toho najlepšieho programátora vytvoriť absolútne bezpečnú internetovú aplikáciu, mojím cieľom je sa k nej maximálne priblížiť. Najzraniteľnejším miestom každej dynamickej stránky sú miesta, kde sa vyžadujú vstupné údaje od používateľa, obzvlášť prihlasovací formulár.
+
CREATE VIEW `rozvrh_view` AS SELECT
 
+
`s`.`name` AS `subject`, `s`.`abbr` AS `subject_abbr`, `s`.`id` AS `subject_id`, `si`.`hours` AS `hours`, `st`.`name` AS `type`, `st`.`color` AS `color`,
Prihlasovanie v našej aplikácií je riešené klasickým HTML formulárom, ktorý pozostáva z dvoch polí: prihlasovacie meno a heslo. Keďže prístup do administračného prostredia bude mať iba jedna osoba, rozhodol som sa uchovávať správne prihlasovacie údaje priamo v prihlasovacom skripte aplikácie. Odpadáva tak porovnávanie vyplnených údajov s údajmi v databáze, ktorej komunikácia so serverom by mohla byť odpočúvaná útočníkom.
+
`tt`.`week` AS `week`, `tt`.`day` AS `day`, `tt`.`hour` AS `hour`, `r`.`room` AS `room`, `r`.`id` AS `room_id`, `tt`.`provides` AS `provides`,
 
+
`u`.`meno` AS `meno`, `u`.`priezvisko` AS `priezvisko`, `u`.`tituly` AS `tituly`, `u`.`katedra` AS `user_katedra`, `u`.`id` AS `user_id`,
Informácia o tom, či je používateľ prihlásený do systému alebo nie, sa uchováva v session. Sessions je technika ukladania informácií na serveri, kedy sa pre každého návštevníka vytvorí súbor s unikátnym náhodným názvom. Tento názov sa následne pošle späť prehliadaču, ktorý si ho ukladá vo forme cookies a pri každej požiadavke na server ho odošle v hlavičke. Bez toho, aby prehliadač serveru odoslal platný názov súboru session mu server prístup k údajom uloženým v session nepovolí. Platnosť session môže ukončiť programátor aplikácie príkazom na zmazanie súboru a cookies, prípadne sa ukončí sama po zatvorení okna prehliadača.
+
`ud`.`abbr` AS `user_abbr`, `ud`.`office` AS `office`, concat('2',`c`.`branch_num`,`c`.`year`,`sc`.`sign`) AS `subclass`,
Sessions sú jedným z najbezpečnejších riešení ukladania údajov pre každého používateľa zvlášť a zároveň je práca s nimi dostatočne rýchla. Ochrana pomocou sessions sa najčastejšie obchádza krádežou identity prihláseného používateľa. Táto technika útoku sa však dá použiť iba v prípade, že útočník môže do stránky vložiť vlastný kód, napr. v diskusnom fóre, čo v prípade našej aplikácie nehrozí.
+
`si`.`rozvrh_subclass_id` AS `subclass_id`, `c`.`branch` AS `branch`, `c`.`branch_num` AS `branch_num`, `sc`.`sign` AS `subclass_sign`,
 
+
`c`.`year` AS `year`, `tt`.`note` AS `note`
Okrem týchto bezpečnostných opatrení sa snažím dodržiavať základné pravidlá pri písaní bezpečnej internetovej aplikácie: nepoužívanie globálnych premenných, filtrovanie vstupu od používateľa, používanie whitelistov.
+
FROM `rozvrh_timetable` `tt`
K základným postupom zvyšujúcim bezpečnosť aplikácie patrí tiež správne nastavenie servera a inštalovanie bezpečnostných aktualizácií. Za to však už zodpovedá správca servera.
+
JOIN `rozvrh_subjectitems` `si` ON `tt`.`rozvrh_subjectItem_id` = `si`.`id`
==Grafický návrh administrátorského prostredia==
+
LEFT JOIN `rozvrh_teachers` `t` ON `tt`.`rozvrh_teacher_id` = `t`.`id`
Pri návrhu používateľského rozhrania sa snažím o maximálny komfort, prehľadnosť a intuitívnosť ovládania. Pomáha mi pri tom hlavne používanie grafických prvkov a implementovanie funkcionalít, na ktoré sú používatelia internetových aplikácií zvyknutí a očakávajú ich, napr. presúvanie objektov, zmazanie objektu po presunutí do koša, zobrazenie dodatočných informácií o objekte pri presunutí kurzoru nad daný objekt atď. Na zabezpečenie takýchto funkcií na internetových stránkach sa používa JavaScript. Keďže je mnou navrhované prostredie pomerne dosť dynamické, potrebuje veľké množstvo JavaScriptového kódu. To 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á.
+
JOIN `eval_users` `u` ON `t`.`eval_user_id` = `u`.`id`
 
+
LEFT JOIN `rozvrh_userdetails` `ud` ON `u`.`id` = `ud`.`eval_user_id`
Ď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 bude používať iba jeden používateľ, ktorý bude o nutnosti mať zapnutý JavaScript upozornený, nebudem tieto opatrenia do kódu stránky vkladať.
+
LEFT JOIN `rozvrh_subclasses` `sc` ON `si`.`rozvrh_subclass_id` = `sc`.`id`
[[Súbor:mpbc1.6.jpg|thumbnail|center|800px|Obr. 2.2 Administrátorské prostredie aplikácie]]
+
JOIN `rozvrh_subjects` `s` ON `si`.`rozvrh_subject_id` = `s`.`id`
Na Obr. 2.2 je znázornená súčasná podoba administrátorskej časti systému. Aj keď tento návrh nie je konečný a pravdepodobne sa bude meniť s pribúdajúcimi funkciami aplikácie, rozloženie hlavných ovládacích prvkov by už radikálnou zmenou prejsť nemalo.
+
JOIN `rozvrh_combinations` `c` ON `s`.`rozvrh_combination_id` = `c`.`id`
===Hlavné menu===
+
JOIN `rozvrh_rooms` `r` ON `tt`.`rozvrh_room_id` = `r`.`id`
Na vrchu 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.
+
JOIN `rozvrh_subjecttypes` `st` ON `si`.`rozvrh_subjectType_id` = `st`.`id`;
[[Súbor:mpbc1.7.jpg|thumbnail|center|800px|Obr. 2.3 Hlavné menu]]
 
Položky menu budú obsahovať odkazy na takmer všetky funkcie aplikácie, napr.: práca s archívom rozvrhu, správa predmetov, správa vyučujúcich atď.
 
===Zoznam priradených predmetov===
 
Tento zoznam (Obr. 2.4) je tvorený tabuľkou, ktorá obsahuje všetky predmety 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 polovice, 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.
 
Obsah bunky tabuľky tvorí skratka vyučovaného predmetu a skratka vyučujúceho v hornej časti a zoznam krúžkov, ktorých sa výučba týka, v dolnej časti. V prípade prednášok, ktoré platia pre všetky krúžky v danom odbore a ročníku, sa v spodnej časti bunky nachádza písmeno P.
 
 
 
Nad tabuľkou sa nachádzajú záložky, na prepínanie dní. 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. Záložkou napravo sa prepína do správy rozvrhu externých študentov, ktorá bude mať iné prostredie.
 
[[Súbor:mpbc1.8.jpg|thumbnail|center|800px|Obr. 2.4 Zoznam priradených predmetov]]
 
===Zoznam nepriradených predmetov===
 
Zoznam nepriradených predmetov (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ť.
 
V spodnej časti sa nachádza zoznam odborov a ich ročníkov. Farba položiek korešponduje s farebným označením buniek v tabuľke priradených predmetov. 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í v zozname priradených predmetov.
 
[[Súbor:mpbc1.9.jpg|thumbnail|center|800px|Obr. 2.5 Zoznam nepriradených predmetov minimalizovaný]]
 
[[Súbor:mpbc1.10.jpg|thumbnail|center|800px|Obr. 2.6 Detaily nepriradených predmetov]]
 
Kvôli veľkosti zoznamu som sa rozhodol pridať funkciu minimalizácie a maximalizácie, takže po vybratí predmetu sa zobrazí stredná časť (Obr. 2.6), v ktorej sa nachádzajú jednotlivé nepriradené hodiny. Naľavo sú typy predmetov, napravo je zoznam krúžkov vo vybratom 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.
 
 
 
Prvky označené veľkým plus slúžia na rýchle pridanie položky daného typu (predmetu, krúžku, nepriradenej hodiny). Po kliknutí na vybratý predmet sa stredná časť skryje a tým sa zoznam minimalizuje.
 
===Kôš===
 
Kôš (Obr. 2.7) slúži na vymazávanie položiek rozvrhu. Nachádza sa v pravom dolnom rohu obrazovky a podobne ako zoznam nepriradených predmetov sa dá presunúť uchopením a potiahnutím. Po presunutí prvku nad kôš (Obr. 2.8) a uvoľnení myši JavaScript automaticky rozpozná typ prvku a odošle požiadavku príslušnému PHP skriptu. Typ prvku sa rozpozná podľa triedy, ktorú obsahuje. Medzi prvky, ktoré sa budú dať takýmto spôsobom vymazať zo systému, patrí: priradený predmet, nepriradený predmet, predmet zo zoznamu predmetov odboru a ročníku, krúžok.
 
[[Súbor:mpbc2.7.jpg|thumbnail|center|Obr. 2.7 Kôš]]
 
[[Súbor:mpbc2.8.jpg|thumbnail|center|Obr. 2.8 Kôš po presunutí prvku]]
 
==Naprogramované funkcie==
 
Zatiaľ sú naprogramované iba základné funkcie potrebné pre vykreslenie administrátorského prostredia. Nasleduje ich zoznam a popis.
 
===Bootstrap===
 
Pri používaní ZF sa stránky nazývajú kontroléry (controller) a ich podstránky akcie (action), takže každý kontrolér môže obsahovať niekoľko akcií. Kontrolér je reprezentovaný triedou a akcie kontroléru jeho metódami.
 
Pre správnu funkčnosť ZF musí byť každá požiadavka na stránku na serveri vnútorne presmerovaná na súbor, ktorý sa nazýva bootstrap. Pre toto presmerovanie sa používa mod_rewrite, ktorý musí byť na serveri nainštalovaný a povolený a príslušný kód v súbore .htaccess (Kód 2.1).
 
<center>Kód 2.1</center>
 
<source lang="apache">
 
Options +FollowSymlinks
 
RewriteEngine on
 
RewriteRule !\.(js|gif|jpg|png|css)$ index.php
 
</source>
 
V bootstrape sa inicializuje ZF trieda Zend_Controller_Front, ktorá podľa tvaru adresy zaistí vyvolanie správneho kontroléru a akcie. Adresa má pritom tvar:
 
<p style="font-family:Courier New">protokol://doména/názov_kontroléru/názov_akcie/</p>
 
Po názvu akcie môžu v adrese nasledovať premenné poslané metódou GET a to buď klasickým štýlom
 
<p style="font-family:Courier New">?premenna1=hodnota1&premenna2=hodnota2</p>
 
alebo štýlom SEF URL
 
<p style="font-family:Courier New">premenna1/hodnota1/premenna2/hodnota2</p>
 
Okrem toho sa do bootstrapu vkladá kód, ktorý sa musí vykonať pri návšteve každej stránky, napr. nastavenie PHP prostredia, inicializácia sessions, pripojenie k databáze, atď.
 
===Prihlásenie do systému===
 
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 trieda 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. Zisťuje sa, či bol formulár odoslaný metódou POST. Kontroluje správnosť údajov podľa filtrov pridelených k daným prvkom formulára. Následne sa porovnávajú údaje so správnymi prihlasovacími údajmi. Ako som už spomínal v podkapitole [[#Bezpe.C4.8Dnos.C5.A5_aplik.C3.A1cie|2.1.3]], 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í sa session s informáciou o stave prihlásenia na hodnotu true. Inak sa označí prvok formulára pre heslo ako nesprávne vyplnené a pridá sa chybová správa.
 
Metóda má návratovú hodnotu buď true – pravda, keď prihlásenie prebehlo úspešne, alebo false – nepravda, keď prihlásenie úspešné nebolo. V tom prípade sa znovu zobrazí prihlasovací formulár spolu s chybou, prečo sa prihlásenie nepodarilo.
 
<center>Kód 2.2</center>
 
<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>
 
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ú ako na stránku s prihlasovacím formulárom, bude na túto stránku presmerovaný. Naopak, ak používateľ prihlásený je, ale zadá adresu na prihlasovaciu stránku, bude presmerovaný na stránku s administračným prostredím. Na túto stránku bude prihlásený používateľ presmerovaný 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. 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.
 
<center>Kód 2.3</center>
 
<source lang="php">
 
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');
 
}
 
</source>
 
===Hlavné menu===
 
Pre vytvorenie a prácu s hlavným menu som si vytvoril triedu My_MainMenu, ktorej konštruktor prijíma ako parameter mnohorozmerné pole s presne určenou štruktúrou (Kód 2.4), ktoré reprezentuje dané menu.
 
<center>Kód 2.4</center>
 
<source lang="php">
 
array(
 
    array(
 
        'label'  => 'Rozvrh',
 
        'js'    => 'rozvrh'[,
 
        ['style' => 'float:right;',]
 
            ['sub'  => array(...)]]
 
    )
 
    [, array(...)]
 
);
 
</source>
 
;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 –
 
;style (nepovinné): CSS vlastnosti danej položky. Tento atribút som pridal kvôli položke Odhlásiť sa, ktorá je od ostatných položiek opticky oddelená
 
;sub (nepovinné): zoznam položiek nižšej úrovne
 
Trieda obsahuje magickú metódu __toString(), ktorá volá metódu na vykreslenie menu automaticky pri pokuse o vypísanie premennej, ktorá inštanciu triedy obsahuje.
 
===Ostatné ovládacie prvky===
 
Pre vykreslenie ostatných ovládacích prvkov potrebujem z databázy vybrať viaceré údaje: študentské kombinácie a krúžky, miestnosti, typy predmetov, názvy predmetov a vyučujúcich priradených k predmetom, určené predmety, neurčené predmety, 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.
 
 
 
Príklad metódy na výber priradených predmetov:
 
<center>Kód 2.5</center>
 
<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>
 
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 a význam niektorých metód:
 
;select(): vytvára objekt Zend_Db_Select pre vytvorenie dotazu na databázu typu SELECT
 
;from($table, $columns): FROM časť dotazu<br>'''$table''' - názov tabuľky. Môže byť typu string alebo array. V prípade typu array kľúč označuje alias tabuľky a hodnota názov tabuľky<br>'''$columns''' - zoznam stĺpcov, ktoré sa majú vybrať. Môže byť typu string alebo array. V prípade array môže byť pole asociatívne alebo číselné. Ak je pole asociatívne, kľúč znamená alias stĺpca
 
;join($table, $condition, $columns), joinLeft($table, $condition, $columns): INNER JOIN, JOIN LEFT časť dotazu<br>'''$table''' - ako vo from()<br>'''$condition''' - podmienka spájania výsledkov<br>'''$columns''' - ako vo from()
 
;fetchAll($select): metóda 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 poľe<br>'''$select''' - dotaz, ktorý sa má vykonať. Môže byť typu string alebo objekt Zend_Db_Select
 
Po vybratí údajov z databázy sa výsledky ukladajú do poľa $return (Kód 2.6) v novom poradí v cykle foreach.
 
<center>Kód 2.6</center>
 
<source lang="php">
 
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,
 
                    'subject'    => T_SUBITEMS.rozvrh_subject_id,
 
                    'comb'      => T_SUB.rozvrh_combination_id,
 
                    'type'      => T_SUBITEMS.rozvrh_subjectType_id,
 
                    'note'      => T_TTABLE.note,
 
                    'subclasses' => array(
 
                        T_SUBITEMS.rozvrh_subclass_id => T_TTABLE.id
 
                    )
 
                )
 
            )
 
        )
 
    )
 
)
 
</source>
 
Tieto mnohorozmerné polia posúva kontrolér skriptu, ktorý sa stará o vykresľovanie stránky. V tomto skripte sa postupným prechádzaním polí vytvárajú 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 kódu (Kód 2.7). Na túto úlohu sa používa 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.
 
<center>Kód 2.7</center>
 
<source lang="html4strict">
 
<script type="text/javascript">
 
    var subjects_added = eval(<?php echo json_encode($this->sub_added);?>);
 
</script>
 
 
</source>
 
</source>
 
<references/>
 
<references/>

Aktuálna revízia z 16:58, 5. december 2010


Systémy pre tvorbu rozvrhu sa, tak ako väčšina aplikácií, v ktorých sú určené úlohy používateľov na základe rozličných stupňov oprávnení, delia na používateľskú a administrátorskú časť. Mojou úlohou bolo vytvoriť administrátorské prostredie aplikácie na správu rozvrhu pre potreby Fakulty mechatroniky TnUAD. Preto sa ďalej v práci budem zaoberať iba touto stránkou aplikácie a používateľské prostredie spomeniem iba v súvislosti s funkciami administrátorského prostredia. Aplikácia dostala názov rozvrhFM.

Použité programovacie prostriedky

Jednou z požiadaviek pri zadaní úlohy bolo, aby bola aplikácia online kvôli možnosti jednoducho pristupovať k nej z akéhokoľvek počítača. Rozhodol som sa preto vytvoriť klasickú internetovú aplikáciu pomocou jazykov HTML a JavaScript, na strane servera potom PHP, čo je v súčasnosti najpoužívanejší serverový skriptovací jazyk. Na ukladanie údajov používam databázu MySQL. Všetky akcie vykonané administrátorom sa prenášajú na server pomocou technológie AJAX, čo eliminuje potrebu opätovného načítavania stránky a zrýchľuje tak prácu s aplikáciou rovnako ako záťaž na server.

HTML

HTML[1] je značkový jazyk určený na vytváranie webových stránok a iných informácií zobraziteľných vo webovom prehliadači. HTML kladie dôraz skôr na prezentáciu informácií (odseky, fonty, váha písma, tabuľky atď.) ako na sémantiku (význam slov). Pôvodne bol určený ako veľmi zjednodušená podmnožina jazyka SGML, ktorý sa používa v organizáciách s komplexnými publikačnými požiadavkami, ale neskôr sa stal samostatným štandardom (ISO/IEC 15445:2000). Špecifikáciu jazyka HTML udržiava World Wide Web Consortium (W3C)[2].

Vo svojej aplikácií používam poslednú verziu, ktorou je HTML 4.01.

JavaScript

JavaScript[3] je skriptovací programovací jazyk používaný najmä pri tvorbe webových stránok. Pôvodne ho vyvíjal Brendan Eich zo spoločnosti Netscape Communications pod názvom Mocha, neskôr pod menom LiveScript. Pred uvedením na verejnosť bol premenovaný na JavaScript, najmä pre vtedajšiu popularitu jazyka Java.

Pre uľahčenie práce s JavaScriptom som sa rozhodol vo svojej aplikácií použiť knižnicu jQuery[4] a jej nadstavbu jQuery UI. jQuery je JavaScriptová knižnica, ktorá zjednocuje funkcie pre rôzne prehliadače, skracuje a zjednodušuje syntax, ponúka funkcie pre prácu s AJAXom a na animácie prvkov internetovej stránky. Jej nadstavba jQuery UI ďalej rozširuje tieto možnosti a ponúka kompletné riešenia najpoužívanejších užívateľských prvkov, napr.: dialógové okná, prepínacie záložky, kalendár, vysúvacie menu atď.

PHP

PHP[5] je populárny open source skriptovací programovací jazyk, ktorý sa používa najmä na programovanie klient-server aplikácií (na strane servera) a pre vývoj dynamických webových stránok.

Pre PHP taktiež existujú viaceré knižnice. Ja som si pre svoju aplikáciu vybral knižnicu Zend Framework vyvíjanú spoločnosťou Zend Technologies[6], ktorá sa taktiež podieľa na vývoji PHP. Ide o plne objektovo orientovanú knižnicu zjednodušujúcu mnohé úlohy od práce s databázou po integráciu so službami iných poskytovateľov, napríklad Google. Zend Framework podporuje a tiež odporúča oddelenie zobrazovania obsahu od vykonávania logiky programu, tzv. MVC (Model-View-Controller) model. Ďalej v práci budem používať niektoré výrazy z terminológie MVC:

  • Model – časť aplikácie, ktorá definuje jej základnú funkcionalitu pomocou skupiny abstrakcií. Môžu v ňom byť definované rutiny prístupu k dátam a základná logika programu.
  • View – presne definuje to, čo je prezentované používateľovi. Obyčajne kontrolér posúva dáta každému view, aby ich zobrazil v požadovanom formáte. View často zbiera údaje od používateľa. Sem sa vkladajú HTML značky.
  • Controller (Kontrolér) – spája celý model dohromady. Narába s modelmi, rozhoduje, ktorý model sa má zobraziť, na základe požiadavky od používateľa a ostatných faktoroch, zbiera dáta, ktoré bude view potrebovať a posúva mu ich alebo predáva kontrolu inému kontroléru.

AJAX

AJAX[7] prakticky nie je programovací jazyk. Je to kombinácia asynchrónneho JavaScriptu a serverového skriptovacieho jazyka. Používa sa na vývoj interaktívnych webových aplikácií, ktoré menia obsah svojich stránok bez nutnosti ich opätovného načítania.

MySQL

MySQL[8] je slobodný a otvorený viacvláknový, viacužívateľský SQL relačný databázový server v súčasnosti vlastnený spoločnosťou Sun Microsystems. Je podporovaný na viacerých platformách a je implementovaný vo viacerých programovacích jazykoch ako PHP, C++ či Perl. Databázový systém je relačný typu DBMS. Každá databáza je v MySQL tvorená z jednej alebo z viacerých tabuliek, ktoré majú riadky a stĺpce. V riadkoch sa rozoznávajú jednotlivé záznamy, stĺpce udávajú dátový typ jednotlivých záznamov, pracuje sa s nimi ako s poľami. Práca s MySQL databázou je vykonávaná pomocou takzvaných dotazov, ktoré vychádzajú z programovacieho jazyka.

Návrh databázovej štruktúry systému rozvrhFM

Jednou z hlavných prípravných úloh pri vytváraní internetovej aplikácie je návrh databázovej štruktúry. Hlavne pri zložitejších aplikáciách, ktoré uchovávajú v databáze veľké množstvo dát, je návrh databázovej štruktúry kľúčovou otázkou. Správny návrh totižto môže uľahčiť vytváranie dotazov na databázu, zjednodušiť zdrojový kód aplikácie, zmenšiť miesto zaberané údajmi databázy na minimum a v neposlednom rade zmenšiť záťaž na server a tým zabezpečiť rýchly a bezchybný chod aplikácie.

MySQL podporuje pre ukladanie dát viacero úložných systémov, nap.: MyISAM, CSV, MEMORY, InnoDB, atď., ktoré sa líšia v ponúkanej funkcionalite a rýchlosti operácií. Pre našu aplikáciu som zvolil úložný systém InnoDB, ktorý je síce pomalší ako predvolený systém MyISAM, ale ponúka funkcionality ako sú transakcie a cudzie kľúče. Ďalšie informácie o databáze sú uvedené v tabuľke 2.1.

Tab. 2.1 Informácie o použitej databáze MySQL
Verzia serveru: 5.1.39-community
Úložný systém: InnoDB
Znaková sada: utf8_general_ci

Aplikácia si bude potrebovať uchovávať informácie o študijných kombináciách, krúžkoch, predmetoch, miestnostiach a vyučujúcich, čomu by mala zodpovedať aj štruktúra tabuliek v databáze. Po dôkladnom zvážení všetkých požiadaviek aplikácie a možností databázy a po porade s konzultantom som sa rozhodol pre riešenie, ktoré je znázornené nižšie (Obr. 2.1). Pri pomenovávaní tabuliek a ich stĺpcov som sa riadil nasledujúcimi pravidlami:

  1. Všetky názvy sú v angličtine, dôvodom je programátorská konvencia
  2. Názvy tabuliek začínajú prefixom rozvrh_ - pre prípad, že by v jednej databáze muselo byť viacero tabuliek patriacich k rôznym aplikáciám
  3. Názvy tabuliek sú v nominatíve množného čísla, okrem tabuliek rozvrh_timetable a rozvrh_timetable_extern
  4. Každá tabuľka má primárny kľúč s názvom id, ktorý je autoinkrementujúci sa (v prvom riadku má hodnotu 1 a v každom ďalšom sa jeho hodnota zvýši o 1)
  5. Stĺpce, ktoré sú cudzími kľúčmi, majú názov ako tabuľka, na ktorú odkazujú v nominatíve jednotného čísla s postfixom _id. Hodnota týchto stĺpcov je totožná s hodnotou stĺpca id v riadku, na ktorý cudzí kľúč odkazuje

Jedinou výnimkou z pravidiel a) a b) je tabuľka eval_user, pretože sa plánovalo, že sa použije už existujúca tabuľka, ktorá sa používa v iných aplikáciách fakulty. Neskôr sa však ukázalo, že aplikácia bude bežať na inom servery, než sa nachádza existujúca tabuľka eval_users. Síce by sa dali používať v aplikácií údaje z tejto vzdialenej databázy, ale nebolo by tak možné plne využiť potenciál použitého úložného systému InnoDB, ktorý nedokáže vytvárať závislosti medzi tabuľkami z rozdielnych serverov. Rozhodol som sa teda vytvoriť kópiu tejto tabuľky v databáze našej aplikácie, ale kvôli nutnosti prepisovať už vytvorený kód som nepristúpil k premenovaniu tabuľky a cudzích kľúčov.

Obr. 2.1 Zvolená štruktúra tabuliek v databáze

Nasleduje podrobný popis jednotlivých tabuliek a vzťahov medzi nimi.

Tabuľka rozvrh_restrictions

Obmedzenia vyučujúcich. Zoznam hodín, v ktoré vyučujúci nemôže učiť.

Tab. 2.2 rozvrh_restrictions – vlastné stĺpce
názov dátový typ popis možné hodnoty
week ENUM('k','p','n') týždeň obmedzenia pedagóga k – každý
p – párny
n - nepárny
day INT(1) číslo dňa 1 – pondelok
...
6 - sobota
hour TINYINT(2) časový slot 1 hodina 8 - 20


Tab. 2.3 rozvrh_restrictions – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
eval_user_id eval_users 1:n nie

Tabuľka eval_users

Kópia vybratých stĺpcov tabuľky použitej v systéme evalvácie fakulty. Táto tabuľka sa nachádza v inej databáze a na inom serveri. V tabuľke sú informácie o pedagógoch na FM.

Tab. 2.4 eval_users – vlastné stĺpce
názov dátový typ popis možné hodnoty
meno VARCHAR(128) krstné meno osoby  
priezvisko VARCHAR(128) priezvisko osoby  
tituly VARCHAR(128) zoznam titulov. Tituly sú oddelené čiarkou  
email VARCHAR(32) email osoby  

Tabuľka rozvrh_teachers

Priradenie vyučujúceho k danému predmetu. K jednému predmetu môže byť priradených viacero vyučujúcich rovnako ako jeden vyučujúci môže byť priradený k viacerým predmetom. Táto tabuľka vznikla pri rozdelení vzťahu n:m medzi tabuľkami rozvrh_subjects a eval_users na dva vzťahy 1:n

Tab. 2.5 rozvrh_teachers – vlastné stĺpce
názov dátový typ popis možné hodnoty
is_lecturer BOOL je alebo nie je prednášajúci 1 – je prednášajúci
0 – nie je prednášajúci


Tab. 2.6 rozvrh_teachers – vlastné stĺpce
názov referenčná tabuľka vzťah môže byť NULL
eval_user_id eval_users 1:n nie
rozvrh_subject_id rozvrh_subjects 1:n nie

Tabuľka rozvrh_userdetails

Doplňujúce informácie o zamestnancovi. Tieto informácie nie sú relevantné v systéme evalvácie FM, preto je vytvorená táto tabuľka.

Tab. 2.7 rozvrh_userdetails – vlastné stĺpce
názov dátový typ popis možné hodnoty
abbr VARCHAR(20) označenie vyučujúceho v rozvrhu, jedinečná hodnota  
office VARCHAR(10) číslo dverí kancelárie zamestnanca  


Tab. 2.8 rozvrh_userdetails – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
eval_user_id eval_users 1:n nie

Tabuľka rozvrh_combinations

Študijné kombinácie na FM.

Tab. 2.9 rozvrh_combinations – vlastné stĺpce
názov dátový typ popis možné hodnoty
branch VARCHAR(5) skratka odboru ME, MKP, MCMV
branch_num TINYINT(1) číselné označenie odboru 1 - 3
year TINYINT(1) ročník 1 - 5
color VARCHAR(7) farebné označenie #RRGGBB

Tabuľka rozvrh_subjects

Zoznam predmetov. V tabuľke nie je informácia o type predmetu ani o dĺžke trvania predmetu.

Tab. 2.10 rozvrh_subjects – vlastné stĺpce
názov dátový typ popis možné hodnoty
name VARCHAR(255) názov predmetu  
abbr VARCHAR(20) skratka predmetu v rozvrhu  
semester ENUM('L', 'Z') semester, v ktorom sa predmet vyučuje L – letný
Z - zimný


Tab. 2.11 rozvrh_subjects – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
rozvrh_combination_id rozvrh_combination 1:n nie

Tabuľka rozvrh_subclasses

Zoznam krúžkov. Krúžky sú označené len dvojčíslom, ktoré tvorí poslednú časť názvu krúžku. Prvé tri číslice skutočného názvu krúžku predstavujú fakultu, zameranie a ročník.

Tab. 2.12 rozvrh_subclasses – vlastné stĺpce
názov dátový typ popis možné hodnoty
sign VARCHAR(2) označenie krúžkov 01, 02 ... – denní študenti
E – externí študenti
note VARCHAR(300) poznámka


Tab. 2.13 rozvrh_subclasses – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
rozvrh_combination_id rozvrh_combination 1:n nie

Tabuľka rozvrh_subjecttypes

Typy vyučovacích hodín.

Tab. 2.14 rozvrh_subjecttypes – vlastné stĺpce
názov dátový typ popis možné hodnoty
name VARCHAR(10) slovné pomenovanie prednáška, labák, cvičenie, konz.
color VARCHAR(7) farba pri prezentácii rozvrhu #XXXXXX

Tabuľka rozvrh_subjectitems

Prepojovacia tabuľka, prepojuje predmet s typom predmetu a krúžkom

Tab. 2.15 rozvrh_subjectitems – vlastné stĺpce
názov dátový typ popis možné hodnoty
hours TINYINT(1) dĺžka vyučovacej hodiny 1 - 9


Tab. 2.16 rozvrh_subjectitems – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
rozvrh_subject_id rozvrh_subjects 1:n nie
rozvrh_subjectType_id rozvrh_subjecttype 1:n nie
rozvrh_subclass_id rozvrh_subclasses 1:n áno, ak majú všetky krúžky hodinu spoločne

Tabuľka rozvrh_rooms

Zoznam učební a ich vlastnosti.

Tab. 2.17 rozvrh_rooms – vlastné stĺpce
názov dátový typ popis možné hodnoty
room VARCHAR(10) označenie učebne  
capacity TINYINT(2) počet krúžkov, ktoré sa do učebne zmestia 1 - 99
note VARCHAR(255) poznámka  
type ENUM('p','s','l')   p - prednášková
s - seminárna
l - laboratórium

Tabuľka rozvrh_timetable

Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - denné štúdium

Tab. 2.18 rozvrh_timetable – vlastné stĺpce
názov dátový typ popis možné hodnoty
provides VARCHAR(8) skratka katedry zabezpečujúcej predmet  
week ENUM('k','p','n') týždeň konania výuky k - každý
p - párny
n - nepárny
day TINYINT(1) číslo dňa výuky 1 - pondelok
...
5 - piatok
hour TINYINT(2) začiatočná hodina výuky 8 - 20
note VARCHAR(255) poznámka  


Tab. 2.19 rozvrh_timetable – cudzie kľúče
!názov referenčná tabuľka vzťah môže byť NULL
rozvrh_teacher_id rozvrh_teachers 1:1 áno - vyučujúci zatiaľ nebol pridelený
rozvrh_subjectItem_id rozvrh_subjectitems 1:1 nie
rozvrh_room_id rozvrh_rooms 1:n nie

Tabuľka rozvrh_timetable_extern

Jednotlivé položky rozvrhu, konkrétne predmety s priradeným časom výučby, vyučujúcim a miestnosťou - externé štúdium

Tab. 2.20 rozvrh_timetable_extern – vlastné stĺpce
názov dátový typ popis možné hodnoty
provides VARCHAR(8) skratka katedry zabezpečujúcej predmet  
week DATE týždeň (lepšie povedané deň) konania výuky  
since TIME čas začiatku výučby  
till TIME čas konca výučby  
note VARCHAR(255) poznámka  


Tab. 2.21 rozvrh_timetable_extern – cudzie kľúče
názov referenčná tabuľka vzťah môže byť NULL
rozvrh_teacher_id rozvrh_teachers 1:1 áno - vyučujúci zatiaľ nebol pridelený
rozvrh_subject_id rozvrh_subjects 1:n nie
rozvrh_room_id rozvrh_rooms 1:n nie
rozvrh_subclass_id rozvrh_subclasses 1:n nie

Pohľady

Okrem spomínaných tabuliek som v databáze vytvoril dve pohľady (views) – rozvrh_view a rozvrh_view_extern. Pohľady sú virtuálne tabuľky - na rozdiel od normálnych tabuliek neobsahujú žiadne údaje, ale iba SQL dopyt, ktorý vyberá z jednej, ale častejšie viacerých tabuliek údaje a spája ich podľa zadaných kritérií. Používajú sa hlavne v prípadoch, že sú spolusúvisiace údaje rozdelené do viacerých tabuliek. Pri výbere z takýchto tabuliek je tvorba dopytov často veľmi komplikovaná, preto je jednoduchšie použiť pohľad. Ďalším prípadom, kedy je vhodné použiť pohľad namiesto prístupu k samotným tabuľkám je, keď viaceré aplikácie zdieľajú tú istú databázu a programátor chce zabrániť niektorým z nich v editácií údajov. Dáta v pohľadoch sú totiž read-only, tzn. určené len na čítanie. Nie je možné cez pohľad údaje do databázy pridávať, meniť ich alebo ich mazať. Na druhú stranu akákoľvek zmena v tabuľkách, z ktorých je pohľad vytvorený, sa okamžite prejaví aj v ňom.

Pohľady v našej databáze obsahujú všetky potrebné informácie o predmete, vyučujúcom, krúžku a čase a mieste konania výučby vo vytvorenom rozvrhu - rozvrh_view v rozvrhu pre denných študentov a rozvrh_view_extern pre externistov. Pohľady budú použité v tých častiach aplikácie, ktoré nepotrebujú práva na editáciu údajov v databáze, tzn. frontend, modul štatistík a exportov a všetky ostatné časti okrem administrátorského prostredia. Oddelenie údajov o rozvrhu pre denných a externých študentov, ako v pohľadoch, tak aj v samotných tabuľkách, bolo pritom nutné kvôli odlišnej relevancií informácií pre oba typy rozvrhov.

CREATE VIEW `rozvrh_view` AS SELECT 
`s`.`name` AS `subject`, `s`.`abbr` AS `subject_abbr`, `s`.`id` AS `subject_id`, `si`.`hours` AS `hours`, `st`.`name` AS `type`, `st`.`color` AS `color`,
`tt`.`week` AS `week`, `tt`.`day` AS `day`, `tt`.`hour` AS `hour`, `r`.`room` AS `room`, `r`.`id` AS `room_id`, `tt`.`provides` AS `provides`,
`u`.`meno` AS `meno`, `u`.`priezvisko` AS `priezvisko`, `u`.`tituly` AS `tituly`, `u`.`katedra` AS `user_katedra`, `u`.`id` AS `user_id`,
`ud`.`abbr` AS `user_abbr`, `ud`.`office` AS `office`, concat('2',`c`.`branch_num`,`c`.`year`,`sc`.`sign`) AS `subclass`,
`si`.`rozvrh_subclass_id` AS `subclass_id`, `c`.`branch` AS `branch`, `c`.`branch_num` AS `branch_num`, `sc`.`sign` AS `subclass_sign`,
`c`.`year` AS `year`, `tt`.`note` AS `note` 
FROM `rozvrh_timetable` `tt` 
JOIN `rozvrh_subjectitems` `si` ON `tt`.`rozvrh_subjectItem_id` = `si`.`id` 
LEFT JOIN `rozvrh_teachers` `t` ON `tt`.`rozvrh_teacher_id` = `t`.`id` 
JOIN `eval_users` `u` ON `t`.`eval_user_id` = `u`.`id` 
LEFT JOIN `rozvrh_userdetails` `ud` ON `u`.`id` = `ud`.`eval_user_id` 
LEFT JOIN `rozvrh_subclasses` `sc` ON `si`.`rozvrh_subclass_id` = `sc`.`id` 
JOIN `rozvrh_subjects` `s` ON `si`.`rozvrh_subject_id` = `s`.`id` 
JOIN `rozvrh_combinations` `c` ON `s`.`rozvrh_combination_id` = `c`.`id` 
JOIN `rozvrh_rooms` `r` ON `tt`.`rozvrh_room_id` = `r`.`id` 
JOIN `rozvrh_subjecttypes` `st` ON `si`.`rozvrh_subjectType_id` = `st`.`id`;