Tweetjeim

Legújabb hozzászólások

szjani

2014. április 18. 22:07

Köszi! Képeket valóban akartam, de nincs normális eszközöm hozzá, ami igényes kimenetet is produkál. :( - Hexagonal arch...

inf3rno

2014. április 18. 14:23

Jó cikk, nekem teljesen érthető volt, szépek a példák is. Annyi megjegyzésem lenne, hogy egy kép többet mond ezer szónál...

Jordan

2014. április 1. 17:31

Interesting project. I recommend using ORM Designer (www.orm-designer.com)in conjunction with Doctrine. It's a great to...

mindegy

2014. február 4. 14:55

Tetszik! A DDD-ről, CQRS-ről még nem hallottam de ha ezekkel így lehet szoftvert fejleszteni, akkor rossz már nem lehet....

szjani

2013. június 7. 21:38

"Maga az event egy string..." - itt valóban pongyolán fogalmaztam, javítom. A több esemény kezelésére a példa:...

EquCMS - Áttekintés

1. módosítás (2011. 01. 10.)

A controllerben immár az alap service osztály van használatban, amihez egy interfészt definiáltam. Így nem muszáj létrehozni egy üres service osztályt minden entity-hez.

Ráértem...

A decemberi szabadságom alatt úgy gondoltam, hogy itt a remek alkalom megismerkedni a Doctrine 2-vel. Rendszeresen Doctrine-t használok és sokszor érdekes jelenségeket tapasztalok a sok "magic" miatt. Az új verzió ehhez képest letisztult, kevésbé "hacky". Gondoltam írok egy Doctrine2 adaptert beberlei ZFDoctrine csomagjához, de rájöttem, hogy egy-két dolgot máshogy csinálnék, így inkább belefogtam egy új CRUD megvalósításba (a komplett rendszer elérhető a GitHUB-on: https://github.com/szjani/equcms)

Elvárások

Első szempont az volt, hogy ne kelljen form osztályt készítenem és ne legyen kötelező azt származtatni valamiféle CRUD-os form-ból. A másik az volt, hogy a validálást domain szintre kell levinni, ez mégis legyen automatikusan elérhető a generált formokban. Fontosnak tartottam azt is, hogy mind a form generálás, mind a fordított, formból entity készítés rugalmas legyen, könnyen bele lehessen nyúlni a folyamatokba.

A CRUD részt perzisztensen tárolt felhasználókon, csoportokon, és ebből generált ACL objektum-ból teszteltem és készítettem el, célom az, hogy az így kialakított rendszerből egy fejlesztőknek szánt, jól konfigurálható és bővíthető CMS-t készítsek. Többek között integráltam a rendszerbe a Symfony DI Containert (az új, Symfony2-ben lévő verziót), beberlei paginator adapterét, valamint a Gedmo-féle nested set repositoryt.

CRUD

Egy általunk írt entity-hez CRUD felületet készíteni két egy lépésből áll:

  1. Elkészíteni a controllert, mely az \Equ\Controller osztályból származik.

  2. Elkészíteni a service osztályunkat, mely az \Equ\Service osztályból származik.

Controller

A controller-ben saját form builder objektumot használhatunk, mely a form készítési folyamatot végzi el. A konkrét elemek generálását factory osztályok végzik. Jelenleg két beépített van a rendszerben: az egyik klasszikus zend form elementeket készít, a másik Dojo elementeket. Az elementcreator objektumok a formBuilder-en keresztül kapja meg az entity validátorait. Ahhoz, hogy ez működjön, az \Equ\Entity oszályból kell örököltetni azt, vagy implementáljuk az \Equ\Entity\FormBase interfészt.

Alap esetben két féle form generálódik: egy a create és update műveletekhez, egy pedig a listázás szűréséhez. Bármely részt kibővíthetjük, vagy akár teljesen újraírhatjuk a controllerünben. Amennyiben a view réteget szeretnénk módosítani, egyszerűen másoljuk át a .phtml fájlokat az Equ/Crud/views/scripts könyvtárból a megfelelő helyre, és írjuk át, amilyenre szeretnénk.

A service osztállyal DTO objektumokkal tartja a kapcsolatot a CRUD controller. Minden konvertálási folyamat (form, entity, DTO) visitor patternnel van megvalósítva, ami szintén nagyfokú rugalmasságot biztosít.

Service

A form generálás és validálás az előző CRUD rendszeremhez képest átkerült a controller oldalra, valamint a validálás a domain rétegbe. A service osztály fér hozzá az EntityManageren keresztül az adatbázishoz. Amennyiben ki akarjuk bővíteni valamelyik folyamatot, úgy azt vagy felüldefiniáljuk a saját service osztályunkban, vagy használjuk a beépített pre*() és post*() hookokat. Az entityBuilder a kapott DTO-ból próbálja frissíteni az entity-t setter metódusokon keresztül. Ha nem találja a metódust, akkor elég származtatnuk a buildert és szintén valamelyik hookban direkt módon módosítjuk az entity objektumot.

Példa

Például a User entity-ben passwordHash member van, a form-ban viszont nyilvánvalóan nem hash-t adunk meg. Ehhez bele kell nyúlnunk mind a form, mind az entity generálásban.

Létre kell hoznunk a service osztályunkat és módosítanunk kell az entityBuildert:

Az entity builderünk az alábbi lesz:

A DTO objektum a $_POST-ból származik, valójában a form példányból készül.

Ahhoz, hogy jelszó mező jelenjen meg a generált formban, valamint eltüntessük a nem kívánt mezőket, az alábbi módon létrehoztam egy formBuildert:

Természetesen ezt még injektálni kell a controllerünkben, amit annak init() metódusában végrehajtunk:

Látható, hogy megadtuk, mely oszlopokat akarjuk kihagyni a litázásból. Az init()-ben átadtuk az imént elkészített, saját formBuilder objektumunknak a Dojo\Factory osztályt, valamint a szűrő formBuilder-ből is sajátot használunk. A getService() metódus egyszerűen kiveszi a Symfony DI containerből a service osztályunkat. A saját, \Equ\Crud\Service osztályból származó osztályunkat itt állítjuk be. Végül látható, hogy a getCUForm() metódust felüldefiniáltuk: ha módosítani akarjuk valamely felhasználót, akkor eltüntetjük a jelszó mezőt a form-ból.

Végszó

A teljes rendszerben még jó néhány funkció megtalálható, mint Zend_Navigation automatikus felépítése, lazy load ACL megvalósítás, ami a role-okat és a jogokat csak akkor próbálja meg betölteni adatbázisból, ha azokat használnánk (így nem kell félni, hogy minden requestnél több tízezer felhasználó kerül be az ACL-be), stb. Még eléggé alfa verzióban van a rendszer, unit teszteket se írtam (hohóóó pedig TDD-vel akartam csinálni), úgyhogy van még mit fejleszteni rajta.

  • Az e-mail cím nem jelenik meg az oldalon, bizalmasan kezelem.

Jordan

2014. április 1. 17:31

Interesting project. I recommend using ORM Designer (www.orm-designer.com)in conjunction with Doctrine. It's a great tool which helps with ORM definition files.

szjani

2011. január 10. 23:58

crystal88_: Megfogadtam a tanácsod, nagyon picit módosítottam az eddigieken, mégis sokkal jobbnak tűnik. Köszönöm (még ha nem is erre gondoltál :).

szjani

2011. január 10. 14:16

Hopp, az viszont abstract osztály elvileg, úgyhogy módosítom. Köszi ezt is!

szjani

2011. január 10. 14:15

Bocs, hogy ledrupalosoztalak :) A interfészes dologgal kapcsolatban lehet, hogy jogos az észrevétel, megvizsgálom, mennyire kivitelezhető. A formokat pedig bár metódusokkal rakja össze a CRUD rendszer, te úgy módosítod őket, ahogy akarod: Zend-ben is használhatsz asszociatív tömböket, kb. úgy, ahogy te is megírtad (látom te szereted :D).

crystal88_

2011. január 10. 14:12

kimaradt (apróság): az AbstractService kicsit megtévesztő osztálynév tekintve hogy nem absztrakt az osztály, én inkább BaseService-nek nevezném el

crystal88_

2011. január 10. 14:10

egyáltalán nem vagyok drupal-os :D és nem arra értettem hogy "bloated" hogy objektum-orientált. Amibe inkább bele tudnék kötni, hogy 1) a Controller meg az AbstractService miért osztályok és miért nem interfészek (látom, hogy azért mert van implementált metódusuk, de inkább azt csinálnám, hogy interfész -> default implementáció (esetleg absztrakt) és akkor ha vki nem akar/tud vmiért az osztályból származtatni, akkor implementálja az interfészt) ezzel kapcsolatban: http://erosbence.blogspot.com/2010/11/using-inheritance.html 2) a formokat jobban szeretem deklaratívan leírni mint metódusláncolással összerakni (nagy formok esetén jobban átlátható) ezzel kapcsolatban saját fejlesztés: http://dev.kohanaframework.org/projects/kform/wiki (több sebből vérzik de a koncepció sztem látszik belőle, azóta újra lett írva jobbra, de az még nem publikus, majd lesz :))

szjani

2011. január 10. 13:54

Köszönöm az észrevételt, a könyvtárat eltávolítom :) A rendszer valóban nem olyan, mint amit általában PHP-ben lát az ember, de mit is kell csinálni? Megcsinálod az entity-t, ami nyilvánvalóan elkerülhetetlen. Ezután elkészítesz két osztályt (service, controller), mindegyikben van 4-5 sor. Ennyi az alap CRUD. Ha többet, vagy mást akarsz, akkor meg van a lehetőséged belenyúlni. És nem végtelenségig passzolgatott tömbökbe kell belenyúlkálni (bocs, ha Drupalos vagy, de az nekem ezért nem tetszik), hanem OOP-vel, letisztult interfészeken keresztül.

crystal88_

2011. január 10. 13:32

sajnos most nincs időm megnézni, de jó cucc. Nekem kicsit bloated, de ettől függetlenül gratula. (a nbproject könyvtárat azért githubra nem biztos hogy fel kellett volna rakni :))

Az adatbázis kezeléshez Doctrine-t használok Az oldal Zend Framework-re épül