Uchwycić moment…

menic’s devBlog

Archive for the 'SparkleWorks' Category

Koniec prac jak makaron

No i znowu długo nic nie pisałem :) SparkleWorks jest prawie ukończone. Pracuje sie na nim całkiem przyjemnie, a nawet bardziej niż całkiem :> Koniec prac jeszcze nie nastąpił i wiele jest jeszcze do poprawienia, ale 2 projekt już na nim kończę :) Do opublikowania sie jeszcze nie nadaje, bo w niektórych miejscach, aż wstyd kod pokazać taki śmietnik jest :| Ale kiedyś myślę znajdę czas i zapnę wszystko na ostatni guzik :D Wtedy pewnie ujrzy światło dzienne... Ale kiedy to nastąpi, to tego nie wiedzą nawet najstarsi górale ;)

Na koniec mały przyklad. Pamiętam jak w Symfony męczyłem sie jak połączyć repopilacje formularza z validatorami. W SparkleWorks to zabawa.

Kontroler:

PHP:
  1. <?php
  2. class ShipmentCompaniesModule extends swAppController
  3. {
  4.  
  5. public function executeAdd()
  6. {
  7. $this->oShipmentCompany = null;
  8. $this->sAction = 'Create';
  9. }
  10.  
  11.  
  12.  
  13. public function executeEdit()
  14. {
  15. $oShipmentCompaniesQuery = new Shipment_companiesModel();
  16. $this->oShipmentCompany  = $oShipmentCompaniesQuery->getByPK( $this->request()->Get( 'id', 'Int' ) );
  17.  
  18. $this->sAction = 'Update?id='.$this->oShipmentCompany->getId();
  19. $this->setView( 'Add' );
  20. }
  21.  
  22.  
  23. public function executeCreate()
  24. {
  25. $oShipmentCompaniesQuery = new Shipment_companiesModel();
  26. $oShipmentCompaniesQuery->setInfo( $this->request()->Post( 'info', 'String' ) );
  27. $oShipmentCompaniesQuery->setName( $this->request()->Post( 'name' ) );
  28. $oShipmentCompaniesQuery->setTelephone( $this->request()->Post( 'telephone', 'Int' ) );
  29. $oShipmentCompaniesQuery->insert();
  30.  
  31. return 'Nowa firma wysyłkowa została utworzona.';
  32. }
  33.  
  34.  
  35.  
  36. public function executeUpdate()
  37. {
  38. $oShipmentCompaniesQuery = new Shipment_companiesModel();
  39. $oShipmentCompaniesQuery->addWhere( Shipment_companiesModel::ID, $this->request()->Get( 'id', 'Int' ) );
  40. $oShipmentCompaniesQuery->setInfo( $this->request()->Post( 'info', 'String' ) );
  41. $oShipmentCompaniesQuery->setName( $this->request()->Post( 'name' ) );
  42. $oShipmentCompaniesQuery->setTelephone( $this->request()->Post( 'telephone', 'Int' ) );
  43. $oShipmentCompaniesQuery->update();
  44.  
  45. return 'Zmiany zostały zapisane.';
  46. }
  47. }
  48. ?>

Szablon:

HTML:
  1. <h3>Dodaj firme</h3>
  2. <?php echo $oForm = new FormHelper( "$__sModule/$sAction" )?>
  3. <?php $oForm->addObject( $oShipmentCompany );?>
  4. <th>Nazwa</th>
  5. <td><?php echo $oForm->inputTextTag( 'name' ); echo $oForm->error( 'name' )?></td>
  6. </tr>
  7. <th>Telefon</th>
  8. <td><?php echo $oForm->inputTextTag( 'telephone' ); echo $oForm->error( 'telephone' )?></td>
  9. </tr>
  10. <th>Dodatkowe informacje</th>
  11. <td><?php echo $oForm->textTag( 'info' ); echo $oForm->error( 'info' )?></td>
  12. </tr>
  13. <th colspan="2"><?php echo $oForm->submitTag( 'Wyślij' )?></th>
  14. </tr>
  15. </table>

Validator:

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <validators enabled="true" module="ShipmentCompanies" action="Create" method="POST"    errorAction="ShipmentCompanies/Add" foreign="false">
  3.  
  4. <name type="string">
  5. <minlenght>3</minlenght>
  6. <maxlenght>255</maxlenght>
  7. <lenghterror>Musi miec dlugosc od {{minLenght}} do {{maxLenght}} znaków.</lenghterror>
  8. </name>
  9.  
  10. <info type="string">
  11. <minlenght>5</minlenght>
  12. <lenghterror>Musi miec dlugosc od {{minLenght}} znaków.</lenghterror>
  13. </info>
  14.  
  15. <telephone type="int">
  16. <typeerror>Muszą być same liczby</typeerror>
  17. <minlenght>8</minlenght>
  18. <lenghterror>Telefon jest za krótki. Min długość to {{minLenght}} znaków.</lenghterror>
  19. </telephone>
  20.  
  21. </validators>

Proste nie :D

9 comments

Moje __autoload() :)

W miare jak SparkleWorks sie rozrasta, coraz trudniej zapanowac nad wszystkimi klasami. Na poczatku wszystko wczytywałem sobie recznie przez include. Było znosnie... ale gdy doszły mi automatycznie generowane klasy modelu, to pisanie

PHP:
  1. include(sciezka/model.class.php;
  2. $o = new Model()

byłoby niesamowicie meczace. Naturalną rzaczą jest, ze pomyslalem o __autoload()
Na poczatku było samo generowanie mapy. Jednak postanowiłem troche rozszerzyc. Do standardowej mapy mozemy dorzucic inne pliki lub tez cale foldery. Wszystko oczywiscie w XMLu :) Teraz moze zaden pozytek, ale z czasem jak zajdzie potrzeba dolaczenia innych bibliotek to bedzie juz to z głowy :)

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <filemap enabled="false">
  3. <files enabled="true">
  4. <class name="auto" enabled="true">E:\auto.php</class>
  5. <class name="test" enabled="true">E:\www\test.php</class>
  6. </files>
  7. <dirs enabled="true">
  8. <dir recursive="true" enabled="true" suffix="class.php">E:\system\classes</dir>
  9. </dirs>
  10. </filemap>

Wyjasniac chyba nie trzeba :)
Pod adresem klasa dla zainteresowanych. Z gory mowie ze jest to czesc SparkleWorks, wiec pewne wstawki z frameworka sa :) Jest to tez wersja robocza, tak wiec nie wszystko jest cacy, ale z gory dzieki za wskazowki :)

4 comments

Zbliża się koniec prac

Powoli zblizam sie do końca prac związanych z SparkleWorks. Teraz jeszcze prace kosmetyczne, dodanie tu i tam wyjątków, komentarzy. Oczywiscie cała funkcjonalnosc jaka sobie wymysliłem nie została zrobiona. Gdybym na to czekał to nigdy pewnie bym go nie ukończył. Do zrobienia na poźniej pozostanie Cache, jakis generator administracji oraz inne przydatne rzeczy. Ale to już po pierwszym wydaniu. Uporządkuje kod i zabieram sie do konkretnej roboty. Jako pierwsze na igien podzie chyba strona kółka KOS. Narazie tylko jeszcze nie wiem jaką funkcjonalnośc musi posiadać, ale jak tylko bede miał plan działania to sie zabieram za realizacje. Mysle ze bedzie to sama przyjemnosc, wykorzystac w akcji SparkleWorks :)
A co do licencji... Jak by ktoś pytał to jeszcze się nie zdecydowałem :P

2 comments

Obsługa bazy danych cd.

Moje wahania co do budowy klasy zarzadzajacej bazą danych już sie skonczyły. Większośc jest gotowa. Do tabel odwołujemy sie przez

PHP:
  1. $o->getPole()

a do złączonych

PHP:
  1. $o->joinedTable->getPole()

. Dzięki temu łatwo było zaimplementować dodatkowe funkcje - jak na razie tylko sprawdzające (reszta wkrótce). Np. jesli dodamy w WHERE pole, ktorego nie ma w tabeli to zamiast czekać na bład bazy danych, sami go wczesniej wyłapiemy :)
Inne smaczki sa przy zapytaniach UPDATE i INSERT. W setterach nastepuje sprawdzanie czy podana przez nas wartosc jest takiego typu jakiego oczekujemy, czy np. nikt nie starał sie wsadzić string'a do int'a itp. Przyda sie pewnie też bajer jak sprawdzanie czy dodalismy wszystkie wartosci. Tzn. Niektore pola sa wymagane jak np. tytuł, a inne (id ktory jest auto_increment) nie. Jesli czegoś nam zabraknie to przy wykonaniu polecenia tez bedzie stosowny bład. Całość oczywiście jest bardzo ładnie generowana automatycznie na pdst. XMLa. Np. taki schemat

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <database name="sw">
  4. <table name="def"><column name="id" type="int" size="10" primary="true" />
  5. <column name="author_id" type="int" size="10" required="true" />
  6. <column name="cat_id" type="int" size="10" required="true" />
  7. <column name="title" type="varchar" size="255" required="true" />
  8. <column name="deleted" type="bool" />
  9. <foreigntable>author</foreigntable>
  10. <foreigntable>cat</foreigntable></table>
  11. <table name="author"><column name="id" type="int" size="11" primary="true" />
  12. <column name="name" type="varchar" size="255" />
  13. <column name="title" type="varchar" size="255" /></table>
  14. <table name="cat"><column name="id" type="int" size="11" primary="true" />
  15. <column name="name" type="varchar" size="255" /></table>
  16. </database>

wygeneruje nam 9(!) plików z kodem PHP :)
Mam do tego jeszcze cache, ale zastanawiam sie nad jego sensem. Wprawdzie przy pobieraniu 5000 tys. rekordów jakas róznica w czasie była, ale niewielka.

3 comments

Obsługa bazy danych

Znowu zawitały ciche dni na blogu :) Spowodowane było to róznymi sprawami (głównie natury uczelnianej). Na razie wszystko sie uspokoiło, wiec coś trzeba skrobnąć. Na chwile obecną męcze sie z klasa do wykonywania polecen na bazie danych. Mam juz praktycznie głowny szkielet oparty na wzorcu AcitveRecord, ale myśle że to za mało. Tzn. zależy pod jakim względem za mało ;) Sama klasa do obsługi zapytan SELECT i UPDATE to niecałe 500 lini kodu bez komentarzy i obsługi wyjątków (gdyz takowej jeszcze nie przygotowałem :/). Mało nie jest. Dużo?... Tez nie.
Do pol w tabeli w przypadku zwykłego select odwołujemy sie po prostu

PHP:
  1. echo $o->Pole

. Do pol z JOINem

PHP:
  1. echo $o->joinedTable->Pole

. Z racji jednak, że bardzo przyzwyczaiłem sie do podpowiadania składni w Eclipse (dzięki NuLLowi [tak sie to odmienia;) ?]) przydałyby sie metody typu

PHP:
  1. echo $o->getPole()

jak w propel'u :) Wiąże sie to jednak ze znaczną rozbudową kodu i troche wiekszą zasobożernością. No bo dla 20 rekordów trzeba 20 nowych rozbudowanych obiektów... Jeszcze musze to przemyśleć (czekam na komentarze :>). Samo generowanie klas trudne nie będzie przy pomocy xml'a, którego bardzo polubiłem, odkąd się z nim zapoznałem. Niech jakies yml'e się chowają :D

2 comments

Mechanizm dostępu do akcji.

Ostatnio zastanawiałem sie jak można rozbudować standardowy mechanizm dostepu do akcji. Ustalamy sobie jakie grupy użytkowników mają dostęp do danej akcji. Działa to ładnie np. credentials z Symfony. Ale mi trzeba czegoś więcej. Pisząc projekt oparty na Symfony, pomyślałem sobie tak: Fajnie by było aby ustawić sobie w credentials np. OWNER i dostęp miał by tylko autor danego postu, czy artykułu. I teraz pisząc system autoryzacji w SparkleWorks postanowiłem jakos ułatwić sprawe i dopisać taką funkcjonalność. Tylko tu pojawia sie problem... Jak rozpoznać, że aktualnie zalogowany użytkownik jest autorem, jeszcze przed wykonaniem akcji?
Na chwile obecną mam pare pomysłów, ale jeszcze nic konkretnego...

3 comments

FrameWork - zastój?

NIE :)

Mało ostatnio pisałem o moim FrameWork'u, ale to nie znaczy ze nic sie nie działo :> Sporo prac nadrobiłem w ten weekend, korzystając z okazji ze jeste sam w mieszkaniu :] Powstała cała konfiguracja, z podziałem na 4 częsci

  • konfiguracja frameworka
  • konfiguracja aplikacji
  • konfiguracja modułu
  • konfiguracja akcji

Długo myślałem nad tym podziałem i doszedłem do wniosku ze taki mi najbardziej odpowiada. Poza tym troche zaczęrpnąłem z symfony, jesli chodzi o odwoływanie sić do konfiguracji. Chodzi mi o przedrostki: sf_ i app_. Zastosowałem podobnie u siebie. Zresztą jest baaardzo podobnie ze względu na skrót: Symfony - sf, SparkleWorks - sw. Zbieg okoliczności :P A jeśli dodać do tego, ze klasy frameworka mają prefix sw, to już całkiem ;) Przyklad

PHP:
  1. swConfig::get('sw_defActDir')

Wygląda znajomo ;-) W ten sposób odwołujemy sie tylko do konfiguracji sw_ i app_. Do pozostałej czesci czyli do modułu i akcji w sposób nastepujący:
Dla aktualnego modułu w którym pracujemy:

PHP:
  1. $this->MOD_CONFIG->zmienna_konfiguracyjna
  2. $this->MOD_CONFIG->Akcja->zmienna_konfiguracyjna

Natomiast jeśli interesuje nas konfiguracja innej akcji, to:

PHP:
  1. $configNewsApp = new swModuleConfig('News');
  2. $configNewsApp->getModConfig()->zmiena;
  3. $configNewsApp->getActConfig()->Akcja->inna_zmienna;

Oprócz konfiguracji powstała klasa typu Input filter działąjąca na Filter Functions z PHP 5.2 oraz klasa swRequest pobierajaca informacje o Requescie współpracująca z Input filter :)
Dodatkowo kolejny raz poprawiłem kontrolery usuwając czesc niezbednego kodu itp. :) Tak wiec dzieje sie sporo.

1 comment

Zmiana struktury MVC w SparkleWork

Chciałem troche odetchnąc, więc postanowiłęm zmienić troche strukture SparkleWorks :). Do tej pory klasa View odpowiedzialna za ładowanie widoków dziedziczyła po klasie AppController, a sama akcja po View. Wyglądało to tak: AppController->View->xxxAction Działało to dobrze, ale z ideologicznego punktu widzenia troche było nie tak. Teraz będzie po prostu AppController->xxxAction no i AppController będzie wywoływać widok jako osobna klase.

Troszeczke trudniejsze do zbudowania, ale myśle że wygodniejsze do poźniejszego używania :)

No comments

Nowa klasa AppBrigde

Aby sie troche odstresować, zacząłem grzebać przy SparkleWorks. Troche poprawiłem AppController, gdyz był mały bug i zacząłem myśleć na konfiguracją. Zrobiłem tak, że do konfiguracji FW oraz aplikacji odwołujemy sie przez Config::getConfig(var), natomiast do konfiguracji modulu przez $this->getConfig(var) Podział taki powstal, gdyz konfiguracja FW oraz aplikacji zawsze bedzie taka sama, natomiast mozemy zechciec pobrac konfiguracje innego modulu niz aktualnie wykonywany. I tu mialem maly problem. Chcialem uniknąć

PHP:
  1. $c = new ModuleConfig('modul')
  2. $c->getConfig(var);

dla pobieranie konfiguracji aktualnego modulu i zastapic przez $this->getSelfConfig(var). Nie mialem gdzie umiescic tej dodatkowej metody. Wpadlem wiec na pomysl klasy AppBridge. Jest to główna klasa Akcji, i inne klasy po niej dziedziczą. Nic nowego to zapewne nie jest, ale stwarza teraz nowe możliwości, co do dalszej rozbudowy :)

2 comments

Wiele akcji w jednej akcji - sukces!

W poprzedniej notce pisałem o moich dylematach co do ładowania akcji w akcji. Teraz, po długich bojach doszedłem do tego co chciałem :D Przyklad:

PHP:
  1. <?php
  2. class DefaultAction extends View
  3. {
  4. public function Index()
  5. {
  6. $this->newModel( 'Show');          //Załaduje nam akcje Show z aktualnego modulu
  7. $this->newModel( 'Show', 'News' ); //Załaduje Show z modułu News
  8. $this->newModel( 'Index', 'Test'); //Załaduje Index z modułu Test
  9. }
  10. public function Show()
  11. {
  12. $this->test = 'zmienna testowa';
  13. }
  14. }
  15. ?>

To był przyklad wykorzystania. To jest dokladnie to o co mi chodziło od początku :) Teraz bez problemu moge napisać moduł News oraz moduł Comments, bez zadnych powiązań między nimi. Zaden z modułów nic nie musi wiedzieć o drugim. Do zrobienia jeszcze zostało mi tylko dodanie parametrów, do nowo wywołanej akcji, ale to już nie problem :)
Dodatkowo, aby sie nie pomylić w szablonach ze zmiennymi, zrobiłem małe udogodnienie. Do zmiennych w szablonie odwołujemy sie w taki sposób: echo $NazwaModułu->zmienna Dzięki temu napewno nie nastapi pomyłka, lub nadpisanie jakiejs zmiennej :)

5 comments

Ładowanie akcji oraz widoków

Jako że przepisuje cały kod, którego i tak było nie wiele, postanowiłem dodać nową funkcjonalność, jaką jest ładowanie klilku akcji w jednej. Już tłumacze na przykładdzie. Mamy moduł News i w nim akcje Show. Oprócz tego mamy jeszcze moduł Comments z akcją ShowComments. I teraz w News->Show() wywołujemy Comments->ShowComments()

PHP:
  1. Class News{
  2. public function Show()
  3. {
  4. //Zawartość akcji
  5. $this->newModel('Comments', 'ShowComments'); //Tutaj wczytujemy moduł Comments z akcją ShowComments
  6. }
  7. }

To był przyklad wywołania. Tak więc to jest to o co powinno chodzić w MVC wg mnie. Np. W tak potężnym Symfony nie ma tego zaimplementowanego. I tam aby wywołać np. komentarze do newsów trzeba było wszystko napisać w akcji newsów. A to mi sie nie podoba!
W teori wygląda ładnie, gorzej z zastosowaniem. Męcze się już nad tym już troche i jakoś nie wiem do końca jak to rozwiązać. Zresztą zainteresowanych zapraszam do dyskusji na ten temat na forum PHP.PL

2 comments

Już coś jest :)

Jak pisałem wczesniej tworze wlasnego frameworka. Do tej pory już całkiem sporo jest zrobione, jeśli chodzi o szkielet. Moze nie jest do idealna implementacja MVC, ale jest. Pisząc SparkleWorks bazuje a dokladniej podglądam troche rozwiązania z Symfony, które uważam za świetne, chociaż troche przekombinowane ;) Jak przeglądam kod to czasami dochodze do wniosku, że wiekszość rzeczy jest poprostu sztuką, dla sztuki. Czyli napiszemy to bo to fajnie wyglada, chociaz jest nie bardzo użyteczne ;)
Ale wracając do frameworka. Najgorzej było na początku zacząć. Stworzyć tą pierwszą klase i funkcje, później nastepną. Miałem wiele pomysłów, tylko nie miałem pomysłu jak przelać to na kod. W koncu sie udało i powstał szkielet.

1 comment

Sparkle It!!!

Długo dojrzewała we mnie myśl stworzenia wlasnego frameworka, aż w końcu sie dokonało :) Po długiej przerwie w zabawie php, trwająca coś ponad rok czasu zacząłem grubej rury :) Najpierw dostałem sie do projektu ToNieProblem.pl z uczelni. Wymagało to nauczenia sie frameworka. Padło na Symfony . Z tego co wyczytałem to mało kto go lubi bo to wielka kobyła i w dodatku bardzo skomplikowana z ogromem konfiguracji. Fakt zgadzam sie :D Ale mi sie podoba. Jednak nie zmiania faktu, że jest kobyłą. Dlatego też do mniejszych rzeczy w ogóle sie nie nadaje. Dlatego też postanowiłem wyjść na przeciw i stworzyć SparkleWork. Kiedyś Sparkle miał być rozbudowanym CMSem, ale teraz bedzie już frameworkiem :)

2 comments