Priklady pouziti Tentokrat zacinam na zadost vedouciho jeste o krok vys nekolika priklady typickeho chovani uzivatele. Doufam ze priste nebudu muset jeste vyse ... uz me nenapada kam. Z vetsi casti se jedna o nudne povidani, ale obcas se tam nachazi vyznamna poznamka. Rozebiram castecne i formularnika a rozhrani s planovacem - ostatni rozhrani rozeberu pozdeji u jednotlivych workflow. 1. Zadani zaznamu: Uzivatel vleze na hlavni stranku caddisu, kde jsi vybere ktery formular chce vyplnovat, vyplni ho (na druhy pokus) a posle. Tento model bude jasne nejcastejsi. 1. Uzivatel vleze na zakladni stranku. Formularnik to pozna jako mezni pripad workflow 1 (zadna cookie, zadne parametry) a zobrazi seznam ktery dostane jako odpoved na volani funkce GetForm planovace. 2. Uzivatel si vybere pomoci jednoho z linku formular ktery chce vyplnovat. (Pripadne si vybere jiny, ovsem na chovani programu se tim nic nemeni :-)). Opet podle workflow 1 (zadna cookie, 1 parametr - kod formulare) formularnik ziska volanim GetForm instrukce k sestaveni stranky, v tomto pripade formulare, a zobrazi ji. 3. Uzivatel stranku vyplni jak nejlepe umi a po dlouhem hledani najde cudlik kterym ji odesle. Formularnik pozna ze se jedna o workflow 2, protoze dostane podstatne vice dat (navic metodou POST) a zavola funkci SendForm planovace se vsemi daty z formulare, pripadne upravenymi podle instrukci z hidden polozek. Tyto polozky mu poslal planovac v ramci formulare. Predpokladam ze jedna z nich je jejich kryptograficky soucet, ktery formularnik overi. Pokud bude sedet, pouzije je, pokud ne, bude verit pouze hidden polozce typ formulare a podle ni si funkci GetForm znovu vytahne instrukce k sestaveni stranky vcetne spravnych hidden poli. Funkce SendForm vrati opet instrukce k sestaveni stranky, ktera bude tentokrat obsahovat formular obohaceny o vstup uzivatele, oznaceni poli (ok,warning,error) vcetne zaveru (Formular obsahuje %i warningu, mohl by jste se podivat zda je spravne ?) a hidden interni klic zaznamu. Pokud mezitim nebyl formularnik ukoncen, zobrazi ji. Funkce GetForm a SendForm budou velmi podobne, vlastne jsem puvodne predpokladal ze se mezi nimi rozlisi prazdnosti posilanych informaci. Obohaceni o vstup uzivatele muze byt primo zahrnuto v jakemsi linearnim toku instrukci k vystavbe stranky, ale predpokladal bych ze vhodnejsi bude kdyz tyto informace budou pripojene k vysledku ktery by dalo GetForm a potrebne spojovani zaridi prave formularnik. V prvnim pripade by ji patrne delal planovac. 4. Uzivatel stranku opet vyplni jak nejlepe umi, tedy opravi vetsinu preklepu ktere udelal a posle ji zpet. Z hlediska formularnika nebude mezi timto a minulym poslanim zadny rozdil, tedy opet workflow 2. Upozornil bych pouze na to ze pokud bude kryptograficky soucet v poradku, krome obvyklych transformacnich pokynu muzeme verit i internimu klici zaznamu (predpokladam ze bude pokryty souctem) a prepsat starou verzi zaznamu misto ukladani nove. 2. Vyhledani a oprava zaznamu: Uzivatel vleze na hlavni stranku caddisu, kde si vybere logovani (obycejny uzivatel tento krok muze vynechat nebo misto toho zvoli personalizaci) potom zvoli hledani, ve vysledku najde zaznam ktery hleda (nepravdepodobne, ale je zbytecne zabyvat se tim jak pracne modifikuje podminky hledani nez se trefi, nebot z pohledu programu budou vsechny tyto hledani stejne) a s pomoci klice nebo faktu ze je prihlasen jako dostatecne opravneny pracovnik si ho necha vypsat, opravi v nem nekolik chyb (0 je taky cislo), odesle a necha vytimeoutovat svoje prihlaseni protoze si urcite nevzpomene se odhlasit. 1. Uzivatel vleze na zakladni stranku. Zadna zmena proti predchozi variante. 2. Uzivatel vybere logovani. To nebude nic jineho nez dalsi formular pro vyplneni jmena (resp. funkce) a hesla. Jedna se tedy o workflow 1. 3. Uzivatel vyplni jmeno a heslo. Jak uz jsem rekl jedna se o vyplneni formulare, z hlediska formularnika tedy priklad workflow 2, i kdyz to vypada extreme. Predpokladam ze i dale se bude jednat o workflow 2 maximalne s drobnymi modifikacemi (nezkontrolovana zadost o login se nezapisuje ... nebo ano ?), pouze na zaver se v pripade uspechu nevrati formular stejneho typu, ale seznam linku podobny zakladni strance - pribude logout a patrne i dalsi polozky pouze pro opravnene osoby. Instrukce k priprave stranky take budou obsahovat pokyn k poslani autentizacni cookie, pripadne k obohaceni linku o autentizacni informaci. Teto informaci bychom mohli rikat SID, prestoze osobne nevidim zadnou vyhodu k pouziti session mechanismu php. Implicitne totiz vytvari soubory, cemuz bychom se meli vyhnout, a jeho uprava pro ukladani do databaze je zhruba stejne slozita jako udelat to rucne. Navic narozdil od diskusniho serveru je mozne ze nebudeme data ze "session" potrebovat tak casto. Predpokladam tedy ze tester pro heslo po overeni spravnosti vygeneruje castecne nahodny vyraz (MD5(random, login)) ktery se ulozi do databaze (v ramci standartniho ukladani otestovanych dat) a posle jako SID uzivateli. 4. Dalsi krok je podobny kroku dva, pouze uzivatel vybere polozku hledani. Jedna se o workflow 1, planovac tedy nevola tester a nijak neoveruje autentizacni informaci, pouze ji posle v instrukcich zpatky. 5. Uzivatel vyplni a odesle hledani. Tento workflow jsem oznacil jako 3. Podle slozitosti hledani muze mit smysl, jak jsem ve workflow 3 tvrdil, overit nektere zadane udaje a upozornit uzivatele na to ze vracena mnozina vysledku vypada jinak nez cekal protoze se pri zadavani preklepl. Kazdopadne ovsem je nutne, at uz pres tester nebo jako zvlastni soucast planovace, overit autentizacni informace a oznacit ktere zaznamy ma uzivatel pravo editovat. Jiste, mohli bychom ho vykopnout az pri kliknuti na prislusny odkaz, ale myslim ze uzivatel ma pravo mit prehled. 6. Uzivatel vybere jeden ze zaznamu. Zde se bude jednat o workflow 4, nebot jeden z parametru bude interni jednoznacny klic zaznamu. Predtim nez vyklopime prislusny zaznam uzivateli musime ovsem zkontrolovat jestli ma pravo ho editovat. Nejsem si jisty jak se v puvodnim caddisu zadaval klic, ja bych volil metodu zapsani na zacatek seznamu vyhledanych zaznamu s tim ze "edit" by byl checkbox a nekde dole by byl submit. Kazdopadne nejak ho z uzivatele dostaneme, ze SID zase urcime jestli neni opravnen diky sve pozici opravnene osoby a pokud jeden z techto testu uspeje, muzeme mu zaznam vyklopit. Pokud navic je opravnenou osobou, musime mu pridat zaskrtavatko na zamknuti zaznamu. Tyto testy pochopitelne nebude provadet planovac, provede je databaze (high-level rozhrani muzeme primo rict SID a klic, low level to dostane jako select klic=$klic as iskey, katedra=$katedraname as isoprkatedra, ...) a vyhodnoti, tedy interpretuje polozky iskey a isoprkatedra, formularnik. 7. Stejne jako v poslednim kroku predchoziho postupu uzivatel zaznam opravi a odesle. 8. Hodinu pote (nebo jiny nastaveny cas) zaznam o tom ze je tento uzivatel prihlasen vypadne z databaze diky pravidelnemu mazani prilis starych SID ktere muzeme provadet bud pri kazdem pristupu do databaze nebo treba pri kazdem pristupu k logovani. 3. Nastavovani pomocnych tabulek: Uzivatel se zaloguje a prida do seznamu clenu katedry noveho cloveka. 1. Zakladni stranka. Workflow 1. 2. Logovani. To uz tu taky bylo. Workflow 1. 3. Uzivatel vybere admin podmenu, pripadne primo polozku modifikace systemovych tabulek. Jasny Workflow 1, ovsem meli bychom overit jeho SID. Zde se ukazuje ze bezpecnost budeme overivat skutecne casteji. Nadale si myslim ze by to mohl byt jen test, ale dost to zavisi na slozitosti testeru. A asi bude bezpecnejsi predpokladat ze to planovac zvladne sam. Tedy, ze se sam zepta databazoveho modulu, protoze SID je spravne tehdy pokud je v tabulce a v temze radku najdeme i uroven opravneni a katedru, pripadne i dalsi informace. 4. Uzivatel vybere ze chce modifikovat prave seznam clenu katedry. Mimochodem, seznam clenu katedry. Nebude mit na vyber ktere. Predpoklada se ze tuto praci budou delat opravnene osoby kateder s pravy pouze do jedne katedry. Jedna se opet o workflow 1 s overenim SID. 5. Uzivatel natuka noveho clena katedry a odesle. Workflow 2. Jiste, musime overit opravneni a pochopitelne dobre vime ze se nejedna o bibliograficky zaznam, ale nevidim duvod proc by do toho melo formularnikovy neco byt. Nebo planovaci. Pochopitelne, tester aplikuje jinou sadu testu a databaze ulozi do jine tabulky. 6. Timeout 4. Nastavovani pomocnych tabulek 2: Uzivatel se zaloguje a smaze cloveka z katedry nebo mu prida novy titul. Hmm ... tak me napada, jak se prenasi clovek z jedne katedry do druhe ? Kdo na to ma prava ? 1. Zakladni stranka. Workflow 1. 2. Logovani. Workflow 1. 3. Admin podmenu. Workflow 1. 4. Seznam clenu katedry. Pro modifikaci muze byt stejna stranka jako pro pridani, vlastne by mela byt, prestoze se bude pouzivat uplne jinym zpusobem. Workflow 4, jedna se vlastne o hledani. 5. Uzivatel si nevsima male tabulky s velkym napisem "pridani noveho clena" a misto toho pouzije kolecko mysi a odroluje ctyri stranky dolu (Moment. Kolik clenu maji katedry ? Hmm ... no mozna ma rozliseni 320x240. Jasne, dela to na palmtopu.) kde najde prislusneho cloveka. Zmackne cudlik nebo odkaz edit, pripadne delete. Workflow 1. 6. Pokud se nejednalo o delete, upravi zaznam. To muze zahrnovat i smazani, pokud bude z nejakeho duvodu az na editacni strance. Formular bude podobny jako pro pridani cloveka (formular, ne stranka), ale v hidden budeme mit napsane ktereho cloveka mame nahradit. Mimochodem, predpokladam ze povolujeme zmenu jmena nebo prijmeni ... Workflow 2. Databaze zaznam nevymaze, pouze nastavi datum ukonceni platnosti a vytvori novy zaznam se stejnym ID. Coz znamena ze nemuzeme pouzivat interni id zaznamu. Respektive, budeme ho pouzivat, nebot vetsinou je dulezite i ktera casova verze se ma pouzit, ale budeme muset mit dalsi id pres ktere napriklad spocitame kolik lidi vlastne na katedre je. Mozna bude stacit rodne cislo ... jenze to bychom meli davat ven jen kdyz je to nezbytne. 7. Timeout 5. Tvorba formularu: Priznavam ze nemam zcela jasno jak tohle realizovat. Proste zadavat formular pres HTTP FORM rozhrani aby to zaroven bylo pouzitelne a zaroven uzivatelsky prijemnejsi nez napsat to textem ... ale mozna ze s pomoci selectu a vhodnych nazvu poli udelame zadavani textem dostatecne pohodlne ... kazdopadne ja bych radsi podle hesla "chlap je schopny tri hodiny premyslet jak si ulehcit hodinu prace" pouzival takovehle rozhranni nez nic. Problem je ze ja si muzu to rozhranni za pochodu upravovat, uzivatele ne. Nebo ze by ... no rozhodne ne tak jako ja. Potom se ovsem bude jednat o stejny pripad jako nastavovani pomocnych tabulek, akorat obsah zaverecneho formulare bude jiny. Z hlediska databaze se bude jednat o ukladani sekvence zaznamu se spolecnym id do tabulky formularu. Tedy, pravdepodobne do nekolika tabulek, protoze napriklad hodnoty a labely selectu nebo checkboxu jsou jasna relace 1:N. Workflow Protoze se na ne odkazuji, zopakuji nyni workflow z minuleho navrhu. Abych usetril praci ctenari vsechny update pisu italikou. 1. Zadost o (vstupni, prvni, trivialne parametrizovany) formular: Puvodni verze predpokladala ze uzivatel zavola formularnika, ten planovac, ktery z databaze spravnym dotazem vytahne strukturu (sablonu) formulare a necha formularnika podle teto sablony sestavit. V nove verzi, pokud jsem spravne pochopil, zaverecne sestavovani provede formularnik volanim XLST sablony s daty z databaze jako parametry. Zda se ze bude zapotrebi v nekterych pripadech overovat jestli dane SID ma dostatecne opravneni k prislusnemu formulari. 2. Odeslani formulare: Zde se mysli predevsim kterykoliv z bibiliografickych formularu, ale stejny workflow bude mit napr. odeslani formulare modifikujiciho seznam kateder nebo casopisu. Zde formularnik prevezme data od uzivatele, podle informaci zakodovanych ve formulari (INPUT HIDDEN) je doplni do uplneho zaznamu (pochopitelne nektere informace se mohou doplnit na zaklade dalsiho pristupu do databaze, ale prijde mi ze se bez toho lze obejit), posle planovaci ktery se uz nebude muset zabyvat tim jaky konkretne to byl formular, ale bude mu stacit zakladni typ - napr vsechny bibiliograficke formulare by mohli byt reseny stejne. V dalsim kroku posle nezkontrolovany zaznam, prislusne oznacen, do databaze pro kazdy pripad. Potom zacne postupne provadet testy, pripadne predpripravi seznam testy a preda modulu tester (druha moznost postavena na miru rozdeleni planovace a testeru se vsemi testy na dva stroje, tester bude kazdopadne velmi primitivni pokud do nej nepocitame jednotlive testy). Vetsina testu bude spocivat v kontrole jedne polozky nebo skupiny polozek proti nejake tabulce s moznymi vysledky ano, ne, seznam podobnych moznosti. Po skonceni testu planovac odesle tyto vysledky (resp vysledky spolu s formularovymi daty) do databaze jako update predchoziho zaznamu, aby je nemusel provadet znova, a vrati formularnikovy ktery je nacpe do formulare a vrati uzivateli (formularnik by mohl mit poznamenano dost dat aby mohl zrekonstruovat formular bez dalsiho pristupu do databaze, nebo mu vysledek tohoto pristupu muze poslat planovac spolu s daty. Vlastni plneni formulare provede kazdopadne formularnik.) Poznamky 1,2 jsou uz vyreseny ... jednoznacny klic zaznamu a uzivateluv klic nebudou mit nic spolecneho. Uzivatel bude sice schopny ziskat nas klic, nebot bude schovany v odkazech na strance, ale tento klic ho nebude opravnovat k editaci. Poznamka: pro interni potreby programu - potvrzovani, zde zmineny update ... se vygeneruje jednoznacny klic i v pripade ze ho uzivatel nezada nebo zada nejednoznacny. Muzeme se rozhodnout ho uzivateli dat nebo ne, ale kazdopadne se muzeme spolehnout ze bez cut&paste si ho nezapamatuje. Poznamka 2: Jake klice vlastne uzivatele voli ? Slo by nejednoznacnost resit (zkusit resit) napr. pridanim jejich jmena ? Poznamka 3: Bibliograficke formulare budou chodit po jednom. Naopak modifikace seznamu kateder nebo schvalovani muze vest k nekolika zaznamum v jednom formulari. Myslim ze nejpozdeji planovac by mel provest rozdeleni. Pokud spojime modifikace a pridani, nebude stranka vypadat nevyuzita a pro hromadny update stejne doporucime import. Takze asi ne. Poznamka 4: komunikace s databazi muze byt i nekolik dotazu po sobe. Zalezi na tom jak mnoho funkcnosti vrazime do databazoveho modulu. Vic nez jeden to ale bude v tomto pripade temer urcite.Naroky na databazovy modul - presneji na high-level rozhranni databaze - rostou. Poznamka ale stale plati. 3. Vyhledavani netrivialni neboli prave: Mysleno podle autora, casopisu, fulltext nebo jineho prirozeneho udaje. Bude probihat podobne jako odeslani formulare s vynechanim odeslani dat do databaze, tedy planovac nejprve kontaktuje tester aby overil smysl zadanych udaju (ovsem i v negativnim pripade vyhledavani provede. Treba dotazem na vsechny autory s titulem MgDr hledame chybne zaznamy ....) a pote provede dotaz do databaze ve forme podobne ukladani dat (databaze provede sice uplne jiny dotaz, nebot data nyni skonci ve WHERE misto v SET, ale to je vlastnost SQL. Umim si predstavit databazi ktera ma vkladani udaju a vyhledavani podle nich velmi podobne. Napriklad neco zalozene na echo a grep nebo na sedu.) Planovac pote vrati formularnikovy jak opraveny formular, tak vysledek hledani a formularnik ho vysype uzivateli podobne jako v predchozim pripade. Jedine formularnik vi, rozumej interpretuje prislusne pokyny, jestli vysledky budou aktivni (tedy budou obsahovat napr cudlik "podrobnosti", budou editovatelne ...) nebo pouze pasivni. 4. Vyhledavani trivialni neboli podle klice: Mysleno bud vyhledani zaznamu podle klice, nebo napriklad vyhledani podle vlajky "schvaleno zadavatelem" & not "schvaleno katedrou". Zde se vyuzije toho ze v techto udajich nejde udelat chybu (resp. jde, ale nejde ji opravit. Kdyz misto klice 1234 zadate 4321, je to chyba ale program nemuze udelat nic lepsiho nez prohlasit ze zaznam s klicem 4321 neexistuje. Nabizet podobne klice by bylo riskantni uz z bezpecnostnich duvodu, o tom jak je poznat nemluve.)Dalsim typickym prikladem bude "hledani" vsech zaznamu v tabulce. Pokud chcete konkretnejsi priklad, vypis vsech clenu katedry je take tento typ hledani. Poznamka: schvaleno zadavatelem se mysli ze nam odsouhlasil vsechny opravy preklepu. Pokud je zaznam v poradku, predpokladame ze je schvaleny i kdyz ho uzivatel podruhe neodeslal, nebot on nemel duvod to delat. 5. Export: Uzivatel ve formulari zada kam si preje exportovat (muze mit jen jednu moznost, nebo treba select ...). Formularnik preda tento udaj, pripadne dalsi udaje (limitni datum) z formulare planovaci, ten je poznamena do databaze (pro cache, viz dale) a hodi exporteru, nebo nejprve provede vyhledavani takovych zaznamu (bude se patrne jednat o jednoduche vyhledavani - "schvaleno knihovnou" & "akademicky rok=..") a pote preda exporteru vysledek tohoto hledani spolu s udaji. V prvni variante pochopitelne prislusny select provede prislusny exportni modul, cimz se sice snizi cistota navrhu ale take spotreba kapacity site. Obecne navic muze dojit k usetreni databaze, nebot zatimco mnozinu zaznamu urcuje planovac, mnozina sloupcu zavisi na formatu exportu. Pravda, i tak to planovac muze udelat, ale opet tim snizi cistotu navrhu. Exporter vyplivne primo vysledny soubor, ktery sice fyzicky pujde zpet pres planovac a formularnik, ale ani jeden z nich ho nebude menit, a skonci tedy jako "Unknown MIME - save to disk ?" v uzivatelove prohlizeci (posychrujeme si to tim ze si prislusne MIME vymyslime, aby to nejaky presprilis aktivni nejmenovany explo ... browser neinterpretoval).application/octed-stream je pry zarucene bezpecny. Pokud bude mit aplikace nejaky zapisovatelny adresar, muze do nej prislusny export ulozit nebo ho ulozit do polozky typu blob v databazi. Planovac potom v pripade stejneho dotazu muze rovnou hodit tento nacacheovany soubor, pokud vi ze se mezitim nezmenili prislusna data (coz bude patrne hadat podle toho ze se nezmenili zadna data). Hlavnim duvodem tohoto kroku bude riziko ze si ten soubor nechaji vygenerovat dva lidi temer soucasne. Vlastne bychom meli chytat i situace kdy druhy pozadavek prijde pred ukoncenim prvniho, pokud bude export tak narocny. Poznamka: rozhodnuti kam ulozit vlastni soubor bych nechal na databazovem modulu. Informace o tom ze dany soubor existuje prijde kazdopadne do databaze a ne vsechny databaze budou disponovat datovym typem schopnym ulozit binarni soubor o velikosti ktera muze presahovat 1MB. Dulezite pro posouzeni zda se mame o neco takoveho starat bude prakticky test s merenim delky generovani exportu. Zatim tezko hadat. Poznamka: predstavuji si podobne chovani jako je u kontroly zapisu - "vas pozadavek se vyrizuje, chvilku pockejte a dejte reload". Pokud totiz bude export trvat dele, muze vytimeoutovat prohlizec, formularnik (bude-li oddelen od exporteru) nebo - nejcasteji - uzivatel. 6. Import: Workflow importu/startovace bude stejne jako workflow odeslani formulare, jen misto formularnika bude importer/startovac. Maximalne muze dojit k odeslani vice bibliografickych formularu najednou.Nebo vice jinych formularu najednou. Kazdopadne prestoze soucasny zapis vice radku tabulky by byl o neco rychlejsi, programovat parallelni testy by byl horror. Jiste, mohli bychom pozadavky rozdelit v planovaci, po jednom otestovat a do databaze poslat zase vcelku. Poznamky Poznamky opisovat nebudu, predpokladam ze si je poctive prectete v predchozim navrhu a posoudite do jake miry jsou jeste relevantni. O pouzivani XML jsme si hezky pokecali, porad si myslim ze to s nim prehanime ale pokud to nebude moje prace tak se s tim smirim ... Interface Tato kapitola mi byla v minulem navrhu agresivne zkritizovana. Dobra, pokusim se nyni nacrtnout jine rozhranni, ktere by vice odpovidalo toku dat. Nadale si myslim ze neni nutne aby modul mel vice vstupu, ale pripadne spojovani vstupu necham na pozdejsi uvahu a v popisu interface je zkusim funkcne rozdelit. Pripadny preklad na predchozi rozhranni by mohl byt zmena vsech vstupnich resp. vystupnich parametru na prvky vstupniho resp. vystupniho pole. Rozhranni uvadim vzdy u modulu jehoz vstupni rozhranni to je. 1. Formularnik: zde stale plati predchozi navrh, tedy: Formularnik bude mit 3 nebo 4 vstupni pole - $_GET, $_POST, $_COOKIE a $_SYSTEM (pro detekci IP). Data v polich $_COOKIE a $_SYSTEM budou patrne pouzita pouze pro personalizaci, $_GET patrne pouze ve workflow 1, ostatni workflow budou prenasena pomoci $_POST. Take by slo pouzit $_SYSTEM['PATH_INFO'] pro workflow 1 misto nebo vedle $_GET, ale zda se ze v tomto pripade to krome faktu ze je to moje oblibena metoda nema zadnou vyhodu. Vystupnim rozhranim je HTML stranka. Narozdil od stranek puvodniho caddisu by patrne mohla byt XML-kompatibilni (nebo jak se jmenuje ten duvod proc se misto
pise
... no jeste to muze byt SGML). Neuskodila by ji ponekud vetsi hlavicka. Nove:Zvlastni pozornost nutno venovat vstupu cestiny. V Karline jsou vsechny stranky opecovavany modulem mod_czech, ktery poctive vyplnuje promenne INPUT_CHARSET a podobne. Neni mi zcela jasne na zaklade ceho hada jak uzivatel zadaval cestinu, ale asi si je tim celkem jisty. Kazdopadne lze predpokladat ze bude stat i pred caddisem a je tedy nutne s jeho pritomnosti pocitat a nastavit spravnou vstupni a vystupni znakovou sadu. Pokud dotycny modul pred nami stat nebude, je nutne se o cestinu postarat rucne. Zde by pomohlo zjistit jak vlastne dotycny modul pracuje a napodobit jeho chovani, nebot standardy nam zajistuji znamou znakovou sadu pouze v POST multipart/form-data, zatimco tento modul i v mnohem efektivnejsim obycejnem POSTu. Predpokladam ze vlastni prekodovani cestiny problemem nebude - bez dodatecnych knihoven je mozne pouzivat PHP rozsireni mb_string, ktere umi UTF-8 a komplet ISO-8859, zatimco kodovani do CP1250&spol zvladne jednoduche strtr. Druha vec na kterou si musime davat pozor jsou naopak neceske znaky - nepredpokladam ze nam tam nekdo bude klafat japonstinu, ale v ISO-8859-2 pry nejde psat svedsky. Myslim ze bychom meli umoznit uzivateli dve varianty: 1) vstup v unicode, ktery bude vyhovovat tem co maji unicode klavesnici (alias klasterni varhany) nebo klavesnici ktera s pomoci unicode zvlada znaky z vic nez jednoho ISO-8859 kodovani. 2) metodu jak jakekoliv pismeno, tedy i ceske pro ty co nemaji ceskou klavesnici, zadat pomoci nejakeho kodu. Primo se nabizi HTML kodovani, pro matematiky bude mozna vhodne i texovske kodovani a mozna najdeme jeste neco lepsiho. Takove kodovani by patrne muselo byt volitelne, tedy implicitne vypnute a jit zapnout, nebot ztizi zadavani jinych znaku (v pripade HTML treba &). Formularnik patrne v ramci podpory XML predavani dat bude vstup konvertovat do UTF-8. Pozdeji, patrne v databazovem modulu, provedeme konverzi na ISO-8859-2 s escape sekvencemi pro ostatni znaky a v takovem kodovani to ulozime do databaze, ktera UTF-8 neumi. 2. Importer: I zde plati predchozi navrh. Importer dostane soubor v nekterem z nekolika podporovanych formatu. Jake formaty budeme podporovat zalezi ciste na nas, myslim ze jeden z nich bude XML soubor konkurencni skupiny. 3. Startovac: Vstupem je mail, predpokladam ze ho dostaneme vcetne hlavicek, a uvnitr mailu bude bud nejaky XML dokument - pravdepodobne nikoliv uplny ale spis jakysi vyrez, protoze malo uzivatelu bude mit chut se opisovat s hlavickou, nebo neco typu 'promenna: hodnota' nebo 'promenna=hodnota'. Zda posilat odpoved, patrne ve formatu HTML nebo shrnuti+odkaz, by bylo nejlepsi se uzivatele zeptat, tedy aby to byla jedna z promennyh. 4. Planovac: Podle nove filosofie by mel mit dve vstupni funkce. GetForm(cislo_formulare,SID) a SendForm(cislo_formulare,data,SID). Obe vraci to same, tedy obvykle instrukce pro sestaveni stranky formulare. GetForm vraci instrukce pro sestaveni formulare cislo_formulare, v SendForm je cislo_formulare cislo toho formulare jehoz data odesilame a odpoved muze byt jiny formular a to dokonce v zavislosti na vstupu (datech). Instrukce pro sestaveni stranky mohou obsahovat parametry a/nebo vysledek SQL dotazu ktery bude pri vlastnim sestaveni stranky pouzit. Alternativne muze posilat exportovany soubor, tedy prima data od exporteru s prislusnou MIME hlavickou. 5. Exporter: Bude balik funkci lisicich se pouze vystupnim formatem (mezi vystupnimi formaty bude RIFF, Procite a nejspise i nejake XML). Funkce budou tvaru ExportXML(podminka_databaze) a budou pracovat tak ze podminku doplni tabulkou a seznamem poli ktere potrebuji a zavolaji databazovy modul. Vysledek dotazu zpracuji do vysledneho formatu. Idealni by bylo dosahnout prutokoveho zpracovani, tedy pokud to dany export umoznuje zpracovavat radek po radku misto ulozeni cele odpovedi do pameti. Vysledny format hodi s prislusnou MIME hlavickou na vystup. 6. Sprava dat: Neboli databazovy modul bude mit dve rozhranni, lowlevel a highlevel. Spravne by highlevel rozhranni melo pouze prekladat pozadavky na lowlevel rozhranni a melo by byt obecnejsi, tedy napriklad ze highlevel modul by byl urcen pro preklad do SQL nebo do obecne relacni databaze a teprve lowlevel by pracoval konkretne s MySQL. Jsem zvedavy jestli to pujde udrzet bez zhorseni efektivity. Obe rozhranni budou ve tvaru [My]SQLquery(goal,method,data,podminka), rozdil bude v detailech - napriklad pro low-level rozhranni bude goal primo seznam tabulek, zatimco pro high-level to muze byt "ZakladniZaznam" ktery ve skutecnosti bude nutne zapisovat do nekolika tabulek. Rozdil bude mozna i v seznamu method, urcite v seznamu operaci ve strome podminek, lowlevel bude muset pouzivat operace v datech zatimco high-level to mozna zakazeme. Krome samozrejmosti jako update, insert, select a virtualni updins bude lowlevel rozhranni muset podporovat i veci jako zamykani nebo vytvareni tabulek. Zatimco zamykani neni problem pridat do tohoo schematu (prazdna data a podminka), vytvareni tabulek vyzaduje ponekud odlisny vyznam polozky data jako seznam dvojic nazev sloupce-typ. Prestoze by to nebyl problem, z hlediska cistoty navrhu by mohl proto skoncit jako MySQLAlterTable(tabulka, seznam atribut-typ, method) s metodami Create, Alter (mozna) a Delete. Vystupem bude v obou pripadech tabulka, tedy seznam sloupcu a seznam seznamu hodnot sloupcu, coz neznamena ze high-level rozhranni bude bez prace - bude muset sestavovat uzivatelske typy ktere cilova databaze nepodporuje, skladat hodnoty vicetabulkovych cilu a podobne. Lowlevel rozhranni bychom nemuseli vubec zpristupnovat nekomu jinemu nez highlevel rozhranni, pokud bude highlevel rozhranni navrzeno dobre. Na druhou stranu pokud predpokladame uzivatelsky zadavane testovaci moduly, budeme muset naopak zpristupnit i primo SQL, tedy dat uzivateli moznost zadat dotaz v SQL ktere zna misto nami vymysleneho formatu ktery nezna, neumoznuje zadat tak komplikovane dotazy jak by chtel a hlavnim duvodem jeho vyvoje je udrzet moznost kompatibility s nejakou pitomou novou modou ktera odeznela kratce po dohotoveni projektu. (Prorokuji extremni priklad. Pochopitelne je mozny i opak, ze se nam budou divit ze neumoznujeme zadavat "normalne" ve formatu dotazu na objektovou databazi nebo co ze to bylo. A cokoliv mezi. Ja osobne ale myslim ze bude trvat jeste hodne dlouho nez nekdo z hlediska efektivity trhne dlouho optimalizovane SQL relacni databaze.) 7. Tester: Uz v minulem navrhu jsem konstatoval ze toto rozhranni je nejtezsi ve smyslu rozmysleni navrhu. Nabizeji se totiz dve rozhranni testu. Za prve jednoduchy test typu "polozka musi byt cislo v urcitem rozsahu delitelne tim a tim" nebo slozitejsi "polozka by se mela nachazet v databazi, ta a ta tabulka s tou a tou podminkou", a za druhe slozitejsi kontroly typu "tyhle tri polozky by se meli nachazet v jednom radku te a te tabulky a kdyz je nektera prazdna dopln ji prave z tohoto radku a kdyz v te tabulce neni musis tam pridat vsechny tyto polozky" nebo "tahle polozka musi tohleto ledazeby tamta polozka tamhleto" (vyskytuje se takovy pripad ? podle letmeho pohledu ne). Logicky s prvnim typem rozhranni nevystacime, zatimco druhe by bylo neefektivni a to i z hlediska programatorske prace. Proto myslim ze samotny tester musi byt pripraven na nejhorsi. Tester tedy bude mit jako primarni rozhranni AplikujTesty(data_z_formulare, seznam_testu). Seznam testu mu vytahne planovac z databaze podle typu formulare. Nebo si ho muze vytahnout sam, seznam testu by mohl byt nazev toho seznamu, tedy treba cislo formulare. Pote podle seznamu pojede jednotlive testy. Jednodussi testy mohou mit rozhranni jako TestIsCislo(udaj, parametr, min, max) nebo TestIsInTable(udaj, tablename, podminka, -id) (podminka muze byt v SQL s tim ze se do jazyka databaze (tedy SQL) prelozi databazovym engine pri vkladani parametru testu nebo serializovana podminka highlevel rozhranni) a vracet 0/1/2 trihodnotovou logiku ok,warning,error nebo slozitejsi strukturu typu seznam pravdepodobnych hodnot & zbytku, napr. TestIsCislo("1800 a nejaky drobny", 1,0,-1)=array("state"=>"1","value"=>"1800","zbytek"=>" a nejaky drobny"). Slozitejsi testy budou mit plne rozhranni, tedy dostanou komplet data z formulare a seznam testu (nevime jestli v nem nejsou nejake parametry ktere by je mohli zajimat) a vrati chybovou zpravu v cilovem formatu. Vystupem testeru bude chybova zprava ziskana zmergeovanim chybovych zprav vsech slozitejsich testu s chybovymi zpravami vygenerovanymi spojenim vysledku jednodussich testu a nazvu polozky na kterou byli aplikovani. Musi obsahovat pocet chyb a warningu a u kazde polozky co neni v poradku seznam navrzenych oprav (muze byt prazdny, ale nemel by byt prilis velky) a zaroven seznam dat z formulare, ale opraveny o jednodussi a jistejsi opravy (tedy uz bude doplneno cislo 1800 misto "1800 a nejaky drobny"). Priklady komunikace Naopak na zadost ostatnich zkusim byt trochu konkretnejsi v prikladech komunikace mezi moduly: vzdy predvedu zadani ve forme php array, tentokrat ovsem formatovane, a ve forme podmnozine XML, ktera by presto v nekterych pripadech zcela postacovala. Snad akorat s vyjimkou tech cisel. Ve vsech prikladech budu vynechavat hacky a carky, prestoze v konecne verzi caddisu samozrejme budou. Nejprve nekolik evergreenu: 1. Priklad instrukci pro formular pridani pracovnika katedry, ktery uz byl vyplnen a vracen z duvodu chybejiciho prijmeni: array( "pagedata"=>array( "0"=>array( <0> "type"=>"title", title "value"=>"Pridani pracovnika katedry %s", Pridani pracovnika katedry %s "par0"=>"katedranamelong" katedranamelong ), "name"=>array( "type"=>"inputtext", inputtext "label"=>"Jmeno", "name"=>"name" name ), "pname"=>array( "type"=>"inputtext", inputtext "label"=>"Prijmeni", "name"=>"pname" pname ), "tituly"=>array( "type"=>"inputcheckbox", inputcheckbox "label"=>"", "name"=>"tituly", tituly "values"=>array( "0"=>"Prof.", <0>Prof. "1"=>"RNDr.", <1>RNDr. "2"=>"Doc.", <2>Doc. "3"=>"Mgr.", <3>Mgr. "4"=>"CSc", <4>CSc "5"=>"Dr.", <5>Dr. "6"=>"DrSc." <6>DrSc. ), "labels"=>array( "0"=>"Prof.", <0>Prof. "1"=>"RNDr.", <1>RNDr. "2"=>"Doc.", <2>Doc. "3"=>"Mgr.", <3>Mgr. "4"=>"CSc", <4>CSc "5"=>"Dr.", <5>Dr. "6"=>"DrSc." <6>DrSc. ) ), "jtitul"=>array( "type"=>"inputtext", inputtext "label"=>"Jiny titul", "name"=>"jtitul" jtitul ), "pozice"=>array( "type"=>"inputselect", inputselect "label"=>"Pozice", "name"=>"pozice", pozice "labels"=>array( "0"=>"prof.", <0>prof. "1"=>"doc.", <1>doc. "2"=>"odb.as.", <2>odb.as. "3"=>"as.", <3>as. "4"=>"ved.ved.prac.", <4>ved.ved.prac. "5"=>"sam.ved.prac.", <5>sam.ved.prac. "6"=>"ved.prac.", <6>ved.prac. "7"=>"odb.prac.", <7>odb.prac. "8"=>"asp.", <8>asp. "9"=>"dokt.", <9>dokt. "10"=>"jn." <10>jn. ) ), "rcislo"=>array( "type"=>"inputtext", inputtext "label"=>"Rodne cislo", "name"=>"rcislo" rcislo ), "1"=>array( <1> "type"=>"inputsubmit", inputsubmit "value"=>"Pridej" Pridej ) ), "pagehidden"=>array( "katedraname"=>"KMA", KMA "formtype"=>"14", 14 "crypt"=>"296c7ea36c4eed5273958802b8423458" 296c7ea36c4eed5273958802b8423458 ), "pageparam"=>array( "katedranamelong"=>"matematicke analyzy" matematicke analyzy ), "warnings"=>"0", 0 "errors"=>"1", 1 "errorvalues"=>array( "0"=>"pname" <0>pname ), "values"=>array( "name"=>"Franta", Franta "pname"=>"", "titules"=>array( "0"=>"Mgr." <0>Mgr. ), "jtitul"=>"", "pozice"=>"3", 3 "rcislo"=>"900202/1234" 900202/1234 ), "sid"=>"15af37dfbb8e4c176017b968dcdbf1c8" 15af37dfbb8e4c176017b968dcdbf1c8 ) Formularnik by mel zobrazit zhruba toto: ---------------------------------------------------------------------- Pridani pracovnika katedry matematicke analyzy Pri zadavani doslo k 1 chybam a 0 nepresnostem. Jmeno: _____________________ +---------------------------------+ | Prijmeni: _____________________ | +---------------------------------+ Prof. [ ] RNDr. [ ] Doc. [ ] Mgr. [ ] CSc. [ ] Dr. [ ] DrSc. [ ] Jiny titul: _____________________ Pozice [_____________] _____________________ [ Pridej ] ---------------------------------------------------------------------- Pochopitelne se jedna jen o priklad, ale myslim ze jsem nezapomel na nic duleziteho. Narozdil od jiz uvedenych prikladu jsem se zameril na hozeni co nejvetsiho procenta prace s pripravou formulare na formularnika - pochopitelne je mozne napriklad seznam chybnych hodnot nahrazen parametrem prislusneho inputu a dokonce mnozstvi prace ktere tim vznikne planovaci a prislusnemu testeru nebude nijak velke. Vlastne konkretne v tomto pripade bych to preferoval, oddeleni by bylo potreba spise v pripade ze zeslozitime metodu zadavani stranky nebo kdyz nebude mozne adresovat polozky formulare jejich nazvem. Na druhou stranu oddeleni hidden polozek (vyklopi se pri submitu) a parametru ma smysl. Alternativni navrh s prevedenim "nevelkych" praci na formularnika: array( "pagedata"=>array( "0"=>array( <0> "type"=>"title", title "value"=>"Pridani pracovnika katedry %s", Pridani pracovnika katedry %s "par0"=>"katedranamelong" katedranamelong ), "name"=>array( "type"=>"inputtext", inputtext "label"=>"Jmeno", "name"=>"name", name "value"=>"Franta" Franta ), "pname"=>array( "type"=>"inputtext", inputtext "label"=>"Prijmeni", "name"=>"pname", pname "value"=>"", "error"=>"1" 1 ), "tituly"=>array( "type"=>"inputcheckbox", inputcheckbox "label"=>"Tituly", "name"=>"tituly", tituly "values"=>array( "0"=>"Prof.", <0>Prof. "1"=>"RNDr.", <1>RNDr. "2"=>"Doc.", <2>Doc. "3"=>"Mgr.", <3>Mgr. "4"=>"CSc", <4>CSc "5"=>"Dr.", <5>Dr. "6"=>"DrSc." <6>DrSc. ), "value"=>array( "0"=>"Mgr." <0>Mgr. ) ), "jtitul"=>array( "type"=>"inputtext", inputtext "label"=>"Jiny titul", "name"=>"jtitul", jtitul "value"=>"" ), "pozice"=>array( "type"=>"inputselect", inputselect "label"=>"", "name"=>"pozice", pozice "labels"=>array( "0"=>"prof.", <0>prof. "1"=>"doc.", <1>doc. "2"=>"odb.as.", <2>odb.as. "3"=>"as.", <3>as. "4"=>"ved.ved.prac.", <4>ved.ved.prac. "5"=>"sam.ved.prac.", <5>sam.ved.prac. "6"=>"ved.prac.", <6>ved.prac. "7"=>"odb.prac.", <7>odb.prac. "8"=>"asp.", <8>asp. "9"=>"dokt.", <9>dokt. "10"=>"jn." <10>jn. ), "value"=>"3" 3 ), "rcislo"=>array( "type"=>"inputtext", inputtext "label"=>"Rodne cislo", "name"=>"rcislo", rcislo "value"=>"900202/1234" 900202/1234 ), "1"=>array( <1> "type"=>"inputsubmit", inputsubmit "value"=>"Pridej" Pridej ) ), "pagehidden"=>array( "katedraname"=>"KMA", KMA "formtype"=>"14", 14 "crypt"=>"296c7ea36c4eed5273958802b8423458" 296c7ea36c4eed5273958802b8423458 ), "pageparam"=>array( "katedranamelong"=>"matematicke analyzy" matematicke analyzy ), "warnings"=>"0", 0 "errors"=>"1", 1 "sid"=>"c9270d805531e2fc1de1b2e1bfbea3e3" c9270d805531e2fc1de1b2e1bfbea3e3 ) V celem prikladu jsem predpokladal ze tituly budu sbirat checkboxy, abych predvedl ze text neni jediny vstup. Nevim jestli v praxi nebude lepsi tituly vypsat do dvou poli - pred a za jmenem. Dalsi velmi zajimavou otazkou je zda tabulka je opravdu spravna metoda zvyrazneni polozky, nebo zda mame zustat pouze u barvy. 2. Dalsi stranka, tentokrat seznam pracovniku katedry - opravdu se mi nechce vymyslet tu obrovsky a neprehledny priklad na seznam publikaci obsahujici zadany string se vsemi jejich polozkami ... jsem dokonce i prilis liny nez abych opisoval skutecne vsechny cleny KMA, kdyz to nema zadny smysl. Nebo hledal novejsi karolinku nez 1998/99. Pole tituly v tomto prikladu by mohlo generovat high-level rozhrani databaze a rovnou do nej hazet i jtitul - mozna by dokonce toto reseni bylo i prakticke. Alternativne bychom museli pouzit mene abstraktni verzi tabulky ktera by umoznila vlozit dva udaje do jedne bunky. Mnoho podobnych detailu bude zalezet na sile XSLT a na tom jak ruzne stranky bude zapotrebi vytvaret. Podobne venujte pozornost udaji pozice - pri zmene ho pouzivame jako cislo, zde musi byt jako string. Opet prace databazoveho rozhranni, i kdyz tentokrat jednodussi, zvlast pokud budeme predpokladat ze se tento seznam nebude menit. Hmm ... neco mi rika ze to predpokladat nebudeme ... Rodna cisla vynechavam umyslne - predpokladam ze v seznamu nebudou. Vlastnost ison v dbselectedit by obecne mela byt 0, 1 nebo nazev polozky. array( "pagedata"=>array( "0"=>array( <0> "type"=>"title", title "value"=>"Seznam pracovniku katedry %s", Seznam pracovniku katedry %s "par0"=>"katedranamelong" katedranamelong ), "1"=>array( <1> "type"=>"caddislink", caddislink "text"=>"Pridej pracovnika", Pridej pracovnika "params"=>array( "formtype"=>"14" 14 ) ), "2"=>array( <2> "type"=>"dbselectbegin", dbselectbegin "format"=>"table", table "border"=>"1" 1 ), "3"=>array( <3> "type"=>"dbselectvalue", dbselectvalue "format"=>"table", table "name"=>"name", name "title"=>"Jmeno" Jmeno ), "4"=>array( <4> "type"=>"dbselectvalue", dbselectvalue "format"=>"table", table "name"=>"pname", pname "title"=>"Prijmeni" Prijmeni ), "5"=>array( <5> "type"=>"dbselectvalue", dbselectvalue "format"=>"table", table "name"=>"tituly", tituly "title"=>"Tituly" Tituly ), "6"=>array( <6> "type"=>"dbselectvalue", dbselectvalue "format"=>"table", table "name"=>"pozice", pozice "title"=>"Pozice" Pozice ), "7"=>array( <7> "type"=>"dbselectedit", dbselectedit "format"=>"table", table "ison"=>"1", 1 "id"=>"id" id ), "8"=>array( <8> "type"=>"dbselectend", dbselectend "format"=>"table" table ) ), "selectdata"=>array( "0"=>array( <0> "name"=>"Franta", Franta "pname"=>"Vomacka", Vomacka "tituly"=>array( "0"=>"Mgr" <0>Mgr ), "pozice"=>"as.", as. "id"=>"1" 1 ), "1"=>array( <1> "name"=>"Jan", Jan "pname"=>"Maly", Maly "tituly"=>array( "0"=>"Doc.", <0>Doc. "1"=>"RnDr.", <1>RnDr. "2"=>"DrSc." <2>DrSc. ), "pozice"=>"ved.prac.", ved.prac. "id"=>"2" 2 ), "2"=>array( <2> "name"=>"Miroslav", Miroslav "pname"=>"Zeleny", Zeleny "tituly"=>array( "0"=>"Mgr.", <0>Mgr. "1"=>"Dr." <1>Dr. ), "pozice"=>"ved.prac.", ved.prac. "id"=>"3" 3 ), "3"=>array( <3> "name"=>"Ludek", Ludek "pname"=>"Zajicek", Zajicek "tituly"=>array( "0"=>"Prof.", <0>Prof. "1"=>"RnDr.", <1>RnDr. "2"=>"DrSc." <2>DrSc. ), "pozice"=>"ved.ved.prac.", ved.ved.prac. "id"=>"6" 6 ) ), "pageparam"=>array( "katedranamelong"=>"matematicke analyzy" matematicke analyzy ), "warnings"=>"0", 0 "errors"=>"1", 1 "sid"=>"1e60931be4937cc44113b2d420a9e4b0" 1e60931be4937cc44113b2d420a9e4b0 ) Vysledna stranka by mela vypadat takto: ---------------------------------------------------------------------- Seznam pracovniku katedry matematicke analyzy Pridej pracovnika +----------------------------------------------------------------+ | Jmeno | Prijmeni | Tituly | Pozice | | |----------------------------------------------------------------| |----------------------------------------------------------------| | Franta | Vomacka | Mgr. | as. | edit | |----------+----------+-------------------+---------------+------| | Jan | Maly | Doc. RnDr. DrSc. | ved.prac. | edit | |----------+----------+-------------------+---------------+------| | Miroslav | Zeleny | Mgr. Dr. | ved.prac. | edit | |----------+----------+-------------------+---------------+------| | Ludek | Zajicek | Prof. RnDr. DrSc. | ved.ved.prac. | edit | +----------------------------------------------------------------+ ---------------------------------------------------------------------- 3. Predchozi stranka pochopitelne ziska seznam dotazem na databazi. Tento dotaz bude na highlevel rozhranni vypadat nejak takto (parametry slepeny do jednoho pole, coz stejne budeme muset udelat pred konverzi do XML): array( "table"=>"pracovnici", pracovnici
"method"=>"select", select "data"=>array( "`"=>"simple", <`>simple "0"=>"name", <0>name "1"=>"pname", <1>pname "2"=>"tituly", <2>tituly "3"=>"pozice", <3>pozice "4"=>"id" <4>id ), "podminka"=>array( "`"=>"and", <`>and "isactual"=>"1", 1 "katedra"=>"KMA" KMA ) )
Prislusny SQL dotaz by mohl vypadat takto: SELECT pracovnici.name,pracovnici.pname,concat(pracovnici.titulypred," ",pracovnici.titulyza," ",pracovnici.jtitul) as tituly, pozice.nazev, pracovnici.id from pracovnici, pozice where ((katedra='KMA') and ISNULL(ddate)) and (pozice.id=pracovnici.pozice); A vysledek dotazu na highlevel rozhranni by byl nasledujici: array( "sloupce"=>array( "0"=>"name", <0>name "1"=>"pname", <1>pname "2"=>"tituly", <2>tituly "3"=>"pozice", <3>pozice "4"=>"id" <4>id ), "0"=>array( <0> "name"=>"Franta", Franta "pname"=>"Vomacka", Vomacka "tituly"=>"Mgr.", Mgr. "pozice"=>"as.", as. "id"=>"1" 1 ), "1"=>array( <1> "name"=>"Jan", Jan "pname"=>"Maly", Maly "tituly"=>"Doc. RnDr. DrSc.", Doc. RnDr. DrSc. "pozice"=>"ved.prac.", ved.prac. "id"=>"2" 2 ), "2"=>array( <2> "name"=>"Miroslav", Miroslav "pname"=>"Zeleny", Zeleny "tituly"=>"Mgr. Dr.", Mgr. Dr. "pozice"=>"ved.prac.", ved.prac. "id"=>"3" 3 ), "3"=>array( <3> "name"=>"Ludek", Ludek "pname"=>"Zajicek", Zajicek "tituly"=>"Prof. RnDr. DrSc.", Prof. RnDr. DrSc. "pozice"=>"ved.ved.prac.", ved.ved.prac. "id"=>"4" 4 ) ) Krome toho se z databaze bude tahat tvar formulare. Myslim ze pokud bude navod ke stavbe stranky postaven tak jak navrhuji, bude nutne ho do databaze ukladat obecnou metodou (jako je PHP serializace nebo XML) do jednoho pole (+ pomocna pole jako id, cislo formulare ...). 4. V prvnim priklade jsme si naopak ukazovali stranku ktera uz byla vysledkem dotazu. Nejde toho na ni moc predvest, protoze je skoro v poradku, ale alespon nebude tolik psani ... vystup z testu puvodni odpovedi bych si predstavoval takto: array( "errors"=>"1", 1 "warnings"=>"0", 0 "values"=>array( "name"=>"Franta", Franta "pname"=>"", "Tituly"=>"Mgr.", Mgr. "pozice"=>"3", 3 "rcislo"=>"900202/1234", 900202/1234 "katedraname"=>"KMA", KMA "formtype"=>"14" 14 ), "errorvalues"=>array( "pname"=>array( ) ) ) Priklady tabulek Kdyz uz jsem si to kvuli predchozim prikladum tak dobre rozmyslel, zde je jak by mela vypadat tabulka pracovniku: * Kod katedry. * Fakulta, pokud nebude mit kazda vlastni databazi jako ze asi ano. * Id zaznamu. Autoincrement. * Id autora. Leda bychom pouzili rodne cislo. Nevi nekdo jestli se meni, rekneme treba pri ufiknuti ... teda te operaci co podstupuji transsexualove ? Ze mohou byt dva lidi se stejnym cislem vim, ale snad se jednalo o ojedinely incident. * Datum vlozeni. * Datum vymazani. NULL pro platny/aktualni zaznam. * Jmeno * Prijmeni * Tituly. Skoro urcite alespon dve polozky. Muzeme si dovoli vrazit jun./sen. do titulu ? * Pozice pracovnika. * Rodne cislo. * Platnost. Zde zaznamename jestli se jedna o skutecnou osobu nebo si jen nekdo nedal rict pri zadavani publikace ... Predpokladam ze nema smysl aby kazda katedra mela vlastni tabulku, ze se vsichni autori vejdou do jedne. Hmmm ... autory odjinud muzeme mit v jine tabulce, ale spis by se meli hodit sem, coz ovsem znamena pridat dalsi polozky - minimalne pracoviste. Ovsem okoli to budeme prezentovat jako dva ruzne seznamy, kvuli opravneni. Mimochodem, kdo ma opravneni pridavat osoby z jinych skol ?