Showing posts with label form. Show all posts
Showing posts with label form. Show all posts

Wednesday, February 29, 2012

Az Art-Work.hu története (Murányi S.)

Az Art-Work (http://art-work.hu) története 2007-ben kezdődött el, amikor egy szakdolgozat témájaként jött létre. Mivel én magam is szeretek fotózni, így nem csak a szakdolgozat viszonylag hamar kikerült a netre (deviantart, stockexpert ihletésére). Reklámozni akkoriban csak iwiw-en reklámoztam, illetve készült pár száz szórólap, amit pár városban művészeti iskolákban szórtunk ki.

2007-2009 -ig három verziót élt meg az oldal. A verzió váltás okai a szakmai fejlődésem volt elsősorban.
Az első nagyobb lépés a 2009-ben PRADO-ra váltás volt, amikor már némi web2 is bekerült az oldalba, és mégis csak egy összeszedettebb rendszer volt, mint az addigiak. A PRADO-t nagyon szerettem, mert jó volt használni, megvoltak a megfelelő dolgok, nem kellett semmiben feltalálni a spanyol viaszt. 

2009-2011-ig sajnos nem nagyon volt foglalkozva az oldallal az akkori munkahelyem miatt, ezért a felhasználói bázis szép lassan el is felejtette az oldalt. Így az addig összegyűlt 1000 felhasználó és 8000 kép ott maradt.
2011 végén, munkahely váltás után lett szabadidőm ismét, és az akkor már általam használt Yii-ben gondoltam, hogy újra írom az oldalt.

Így az már működik és ismét zajlik az élet :)

A Yii-re azért váltottam PRADO-ról, mert ugyan az MVC nagyon új volt a PRADO felfogásával szemben, ám sebességben olyan szakadék tátongott a kettő között, hogy egyértelmű volt a váltás. Megnyugtató volt számomra, hogy a Yii egyik fejlesztője a PRADO volt alapítója, így egyértelmű volt, hogy minőségi keretrendszer ez is.

Yii-ben kihasználok mindent, amit lehet, de azért pár dolog, aminek nem tetszik a működése, azt inkább magam készítem. Ilyen például az assetek kezelése. Nem szimpatikus, hogy egy mappában random dir-be kerülnek az assetek, és ha kiviszem production-be az alkalmazást, akkor új dir-ek generálódnak. Inkább én belinkelem magamnak, ami éppen kell. Remélem ezt valamikor átalakítják.

Nem szoktam használni a grid-et például, inkább saját foreach ciklust használok, mert felesleges extra lépcsőként tekintek erre a lehetőségre.

Kiegészítettem a rendszert egy saját DataType osztállyal és annak leszármazottjaival, mellyel igyekszem a PHP laza típus kezelését kivédeni. AJAX kommunikációnál és minden klienstől REQUEST-ben érkező adatnál kialakítottam egy DTO (Data Transfer Object) rendszert, ahol előre definiált adatok közlekednek az objektumok között, nem csak feltöltöm a model attributes property-jét a POST-ból érkező adattal. Így pl, mivel külön class-ban van mondjuk egy form-tól várt mezők, jól látható, hogy mi az, és csak az, amit a klienstől várunk. Nagyjából a CFormModel is ezt oldja meg (ha jól tudom), próbáltam is használatát, de kevésbé volt szimpatikus, mint a saját megoldásom.

Ha elakadok, sokszor segít a Yii fórumban keresgélés, de a stackoverflow-n is nagyon sok Yii-s problémára találok megoldást.

Amit viszont örömmel használok a Yii alap lehetőségeiből és letölthető extension-jaiból: EAjaxUpload, urlManager, YiiMail, I18N

Amit még fontosnak tartok megemlíteni, mert sokat könnyít a fejlesztésen, az az, hogy az I18N modult kiegészítettem egy wrapper osztállyal, amit ugyanúgy kell használni, mint a Yii által adott default tool-t, annyi különbséggel, hogy nem kell magunknak belerakni az új fordítandó szavakat az adott dictionary php-ba, hanem magától belerakja, ha még nincs benne, illetve a file-t is létrehozza, ha még nincs. Ez a felfogás a PRADO-ból jött, mert ott is nagyon tetszett, hogy ezt megcsinálja helyettem. Ezt a Yii fórumon meg is osztottam természetesen.

Jelenleg a UNIT tesztek írását készítem, ahol azért néha rájövök, hogy nem teljesen sikerült minden részt tesztelhetőre készíteni. Ezért is alakítottam ki a DTO környzetet például.

-- írta  Murányi Sándor

Tuesday, July 26, 2011

Gittegylet meg a Yii - avagy Yiiki 2.0 (3. rész)

Akik még mindig olvassák ezt a cikk sorozatot, azoknak KÖSZI. Akik csak most probálkoznak bekapcsolódni, azoknak mindenképp ajánlom az előző két rész elolvasását hiszen ott ismerkedtünk meg olyan dolgokkal mint a yiic parancs, Git forráskezelő és a Gii kódgeneráló.

Az előző részt ott fejeztük be, hogy a Gii segítségével elkészítettük a Page modell osztályunkat a pages táblához. Ha most megnézzük, hogy hogy áll a forrásunkat (git status) akkor láthatjuk, hogy egy Page.php file jött létre a protected/model/ mappán belül. Ezt hozzá is adhatjuk a szokásos git add paranccsal. (A Git-ről itt van egy leírás magyarul a BME oldalain. Ebben a cikk sorozatban már csak a végén vesszük elő mégegyszer, amikor publikáljuk a programunkat).

CRUD

Azzal, hogy elkészítettük a Page modellünket, még semmi, böngészőben látható eredményt nem sikerült produkálnunk. Itt jön a CRUD a képbe,

Create - Létrehoz
Read - (Be)olvas
Update - Frissít
Delete - Töröl

Most megint vegyük elő a varázságyúnkat (Gii) és belépés után kattintsunk a Crud Generator linkre. Ha minden igaz, egy két mezős form-ot kell kapnunk, ahol valójában elég csak az első mezőt kitölteni a Model Class-t azaz Modell Osztáy-t, a Controller ID-t a Gii magától kitalálja. Jó mi? (Megj: a Base Controller Class és a Code Template útvonal is átírható, így ezek segítségével ha akarjuk teljesen újraírhatjuk a Gii viselkedését.)

Tehát írjuk be a Model Class-be, hogy Page és nyomjuk meg (csak egyszer!) a Preview gombot. Ha valami ilyesmit látunk akkor örülhetünk:



Itt már lényegesen több file fog elkészülni mint a modell létrehozásánál. Láthatjuk, hogy maga a Controller (vezérlő) is elkészül majd, a view/page mappa is, ahol a rendszer fogja tárolni a szükséges nézet file-okat (create.php, update.php, view.php stb). Ha minden OK, nyomhatunk a Generate-ra.

A programunk jelenlegi állapotában már mindenre kész. Tudunk oldalakat listázni, készíteni és törölni. Hogy megbizonyosodjunk róla, böngészőnkkel látogassuk meg a következő URL-t:

http://localhost/index.php?r=page

Na de mi nem elégszünk meg ennyivel, hiszen egy igazi Wiki-t szeretnénk készíteni. Jöhet a testreszabás ...

Testreszabás

Beviteli form módosítása

Ha most probálnánk egy Page-t azaz Oldalt készíteni (http://localhost/index.php?r=page/create), akkor azonnal észlelnénk, hogy a beviteli form-on egy csomó olyan mező van, amit nem szeretnénk kézzel minden egyes alkalommal kitölteni, illetve elvárnánk a programunktól, hogy saját maga töltse ki. Ilyen például a created vagy a revision mező.

Módosítsuk is a form-unkat valahogy így:



A Page Modell Szabályainak Beállítésai

A Page (Oldal) modellünkre is ráfér egy kis farigcsálás. Ugyan Gii többnyire kitalálta, hogy milyen szabályokat hozzon létre a különböző form mezőkhöz, a gondolatolvasástól azért még messze van.

Mi ugyanis szeretnénk, ha az Oldalunk címébe csakis betűk, számok, vagy aláhúzás jel szerepelhessen. (Egy jó kis bővítés lenne, ha a programunk automatikusan felülírná a bevitt a címet, de az példa kedvéért itt egy szabályt hozunk létre)

protected/models/Page.php



Az itt használt szabályok elég egyértelműek, de ha valaki jobban bele szeretne mélyülni itt olvashat róluk bővebben: http://www.yiiframework.com/doc/cookbook/56/

Itt még azt is megfigyelhetjük, hogy hogyan kell a programunkat magyarul tanítani ;)

A beforeSave() and save() modell függvények használata/felülírása

A modelljeink, amik a programunkban az adatbázis lekérdezéseket kezelik, mindenféle függyvényekkel fel vannak fegyverkezve, hogy nekünk ne kelljen védőkesztyű nélkül SQL-kódban kotorászni. Az egyik ilyen függvény a save() (mentés) és hű csatlósa a beforeSave() (mentés elött elment). A save() egy adatbázis rekordot köteles elmenteni vagy felülírni.

A pages adatbázis táblánkban van egy olyan mező, hogy created (készítve), ami egy dátum mező. (a példánkban UNIX Timestamp-et használunk!) Ez a mező tartja nyilván, hogy az adott oldal mikor lett készítve/felülírva. Ugyan használhatnánk a save() függvényt arra, hogy ezt az értéket beállítsuk, a példa kedvéért ezt a beforeSave()-vel oldjuk meg.

(Az fontos, hogy itt a szülő beforeSave()-jével térjünk vissza, return parent::beforeSave() )

protected/models/Page.php



Néha előfordul, hogy még a form mezők ellenőrzése elött szeretnénk beállítani valamilyen értéket, ezt a beforeValidate() funkcióval tehetjük meg.

A save() függvénynél már kicsit más a helyzet. Először vegyük sorra, hogy mit is szeretnénk a programunktól, amikor elmentünk egy oldalt. Ha minden igaz, említettük az elején, hogy a jövőben szeretnénk egy revert opciót, ami annyit jelent, hogy az odalalainkat, ha akarjuk, visszaállíthatjuk egy korábbi változatba. Ezt többféle módon is meg lehet valósítani, de talán a legrövidebb megoldás, ha az oldalakat mindig újként mentjük el, és csak növeljük a revision azaz verziószámot.

protected/models/Page.php



A Yii modell osztálya olyan finomságokkal lát el bennünket, mint például a $this->isNewRecord ami egyszerűen megmondja nekünk, hogy most egy új rekordról van e szó, vagy csak felülírunk egyet. Mi persze tudjuk, hogy nekünk arra van szükségünk, hogy minden egyes oldal újként legyen elmentve, tehát ha az oldal nem új, akkor egyszerűen gyártunk egyet ami a $newpage->attributes=$this->attributes segítségével felveszi az eredeti oldal értékeit.

Még annyit érdemes megjegyezni, hogy ha a save() függvényt false paraméterrel hívjuk meg, akkor az ActiveRecord-ban beállított szabályai nem vonatkoznak az adott rekordra.

Az Oldalak-at lekérő SQL módosítása és a hozzá tartozó Nézet (View) beállítása

Ha most néznénk meg az Oldalak listáját, azt vennénk észre, hogy programunk, az egyes Oldalakhoz tartozó összes reviziót megmutatja. Ez ideáig rendben is van, hiszen minden egyes változatot "új"-ként mentettünk el, azonban ez elég zavaró lehet, meg bugyután is néz ki. Ha eddig még nem említettük volna, majd minden Controller osztálynak van egy úgynevezett actionIndex()-je ami az alapértelmezett függvény. Jelen esetünkben ez szolgáltatja az Oldalak listáját. Keressük is meg a PageController-ben és módosítsuk a következők szerint:

protected/controllers/PageController.php - actionIndex()



SQL-ben valamennyire jártasabbak egyből kiszúrhatják, hogy mi is történik. Itt létrehozunk egy úgynevezett CDBCriteria() osztályt aminek segítségével különböző SQL paramétereket állíthatunk be, és ez által módosíthatjuk a lekérdezéseinket, ami ebben az esetben az Oldalak csoportosítását jelenti a title azaz cím szerint, és rendezést a létrehozás dátuma szerint.

Az alábbi file-okat pedig módosítsuk izlésünk szerint (illetve az én izlésem szerint). Ha még emlékszünk, a PageController-t kicsit átalakítottuk, hogy az adott Oldal azonosító ID-ja helyett a title mező értékével dolgozzon. Ez nagyon szép és jó, de a program többi részét is kicsit át kell alakítanunk. Ilyen például az actionCreate() és actionUpdate() funkciókban használt redirect() ami azt a célt szolgálja, hogy bizonyos események után böngészőnket egy meghatározott oldalra küldje.

protected/controllers/PageController.php



A következő file-ok pedig a megjelenítést szolgálják ...

protected/views/page/_view.php



protected/views/page/view.php



Jajj de jó, már lassan készen is vagyunk. Mondjuk a megjelenített oldal egyáltalán nem úgy néz ki mint egy igazi Wiki oldal. A következő részben megnézzük, hogyan használjuk a Yii-be alapból beépített MarkDown értelmezőt, hogy megússzuk a sok str_replace()-t ;)

Mivel a Wiki alkalmazásunk elég speciális (ID-k helyett a cím alapján találunk meg egy-egy Oldalt), ezért a Page vezérlőnkben elég sok minden változott,úgyhogy a teljesség kedvéért ide betettük az egész osztályt.

Tuesday, January 11, 2011

Egy Modell Validálási Esetei

Ha valakinek van ötlete, hogy lehetne a Validation Scenarios-t szépen magyarra fordítani, ne kíméljen (talán Értékellenőrzési Forgatókönyv-nek vagy Szabályozási Szintek-nek?).

Az 1.0.2-es megjelenése óta lehetőségünk van különböző Validálási Eseteket (Validation Scenario) beállítani modelljeinkhez. Ez nagyon hasznos olyan esetekben, amikor az alkalmazásunk több pontján lehet/kell egy modellen keresztül adatot bekérni a felhasználótól.

Például egy új felhasználó regisztrálásánál valószínűleg a 'felhasználónév' az 'email cím' és a 'jelszó' mezők kötelezőek, míg az 'elfelejtett jelszó' oldalon talán csak az 'email cím'. Itt egyből látszik, hogy ha mind a három mező kötelező alap esetben, akkor az 'elfelejtett jelszó' funkció nem igazán fog működni, hiszen ha felhasználóbarátok akarunk maradni, akkor nem fogjuk bekérni sem a felhasználónevet sem pedig a jelszót (amit úgyis elfelejtett a kedves kis felhasználó ;) )

Tehát hasonló problémákra kínál tökéletes megoldást a Validálási Esetek  használata amiket nagyon egyszerűen állíthatunk be az 'on' paraméterrel a különböző modell szabályokhoz (rules). Az 'on' paraméter talán már ismerős lehet adatbevitelnél (insert) vagy frissítésnél (update) attól függően, hogy melyik mentést (save) használjuk. Elég gyakran ez a kettő nem elég sajnos, viszont ennek az új megoldásnak köszönhetően akarmennyit készíthetünk. Nézzünk is egy példát:
protected/model/User.php



Ezekkel a beállításokkal Yii már tudni fogja, hogy mikor melyik Szabály fusson le. A példa kedvéért persze betettünk egy-két extra szabályt is. Remélhetőleg a megjegyzések elolvasása után már jobban érthető, hogy mire is jó ez az egész. Az összehasonlító (compare) szabálynál látni, hogy több Szintet is meg lehet adni vesszővel elválasztva (pl: 'register,update').

Tehát ha egy modell ellenőrzését (CModel::validate()) szeretnénk elvégezni, egyszerűen adjuk át a Validálási Esetet paraméterként:



Az eredeti cikk, Jonah által: http://php-thoughts.cubedwater.com/2009/validation-scenarios/