Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> dynamiczne rozszerzanie klasy, pluginy - wzorzec?
baniczek
post
Post #1





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 19.07.2007

Ostrzeżenie: (0%)
-----


Witam

Potrzebowałbym nowego podejścia do rzeczy, którą chcę wykonać.
W celu opisania problemu muszę się trochę rozpisać... ;-)

"miniframework" -> generowanie formularzy
klasę Form reprezentującą formularz rozszerzam klasą Form_PHP. w niej w metodzie create() wywoluję metody:

Kod
$this->add_input_text('nazwa', array('class' => 'php'))->add_textarea('nazwa2')->add_input_submit('Zapisz'); itp.


w klasie Form używam metody __call() w celu pobrania nazwy klasy elementu formularza - czyli "add_" jest odrzucane, Input_Text to klasa.

Jest możliwe tworzenie grup (checkbox, radio) metodą:
Kod
$this->add_group('checkboxy[]', array('wartosc_1' => 'label_1', itd), array('class' => 'grupa'));


Problem narodził się z wymogu dodania np. klasy do jednego elementu grupy radio/checkbox - tablice wielowymiarowe to dość średnie rozwiązanie i chciałem wszystko w jednym "łańcuchu" zrobić. Nie chciałem również w klasie formularza tworzyć ręcznie obiektów grupy i dlatego powstało coś takiego:
Kod
$this
    ->group_start('checkboxy[]', array('class' => 'asd'))
        ->add('wartosc_1', 'label_1', array('class' => 'klasa czekboksa'))
        ->add('wartosc_2', 'label_2', array('id' => 'cosinnego'))
        ...
    ->group_end()


To wszystko generalnie działa, lecz problem narodził w czasie kiedy chciałem tą funkcjonalność zamknąć w osobnej klasie.

Utworzyłem proste api do pseudo pluginów, które dynamicznie rozszerzają klasę Form o nowe metody. I tak np. w magicznej metodzie __call() klasy Form odbywa się sprawdzanie (zaraz na początku), czy któryś plugin ma metodę np. group_start(). Z tym nie ma problemów - jak nie ma metody to leci dalej, jak ma - wywołuje.


Jednak w celu ogarnięcia tego chociażby z powodu, że za kilka dni zapomnę co napisałem, chciałem zrobić sprawdzanie czy metoda wywołana na klasie Form istnieje w aktualnie używanym pluginie - w przypadku kiedy metody są zamknięte między innymi. To też działa, ale nie w przypadku, który obecnie rozpatruje:

Zaprezentowana wyżej metoda group_end() wywołuje nic innego, jak metodę (na klasie Form) ->add_group() z odpowiednimi parametrami - czyli jest obsługiwana przez __call() w klasie Form. Z racji, że sprawdzanie czy metoda pluginu istnieje w nim odbywa się zaraz na początku __call() w klasie Form to sprawdzany jest ostatnio używany plugin (czyli ten od grupy, group_start()) i zamiast dodać grupę jest wyrzucany wyjątek, że metoda add_group() nie istnieje w pluginie - co nie jest dziwne.
Mogę przenieść sprawdzanie na koniec __call(), ale wtedy raczej nie możliwe będzie utworzenie lub nadpisanie metody istniejącej w klasie Form, np. w przypadku kiedy zamykam metody między 2 metodami pluginu. Czyli metoda pluginu: add() zamknięta pomiędzy 2 innymi metodami, a metoda add() istnieje w klasie Form i ma całkiem inne zastosowanie niż ta pluginowa - dlatego wywołujemy tą z pluginu jeśli "praca na pluginie" nie została zakończona.

Po co "ostatnio używany plugin"? Np. powyższy przypadek i też po to, że tych pluginów może być wiele i wszystkie mogą zawierać metodę ->add() i żeby w dobrym pluginie ją wywołać to trzeba (?) przechować obecny plugin.
"Pracę na pluginie" w praktyce oznacza wartość zwracana z metody pluginu, np. self::RESULT_PLUGIN - pracujemy na pluginie czyli następna metoda jest brana z tego pluginu (np. ta jedna konkretna metoda add() z wielu metod o takiej samej nazwie w pluginach czy też w klasie Form), self::RESULT_FORM - koniec operacji na pluginie (np. group_end() ją zwraca) czyli zmienna z ostatnim pluginem jest czyszczona, następna metoda to metoda z innego pluginu lub z klasy Form.

Mam jeden pomysł, który rozwiązywałby ten problem, ale nie chcę go stosować (IMG:style_emoticons/default/smile.gif) Tworzę zmienną $_wylacz_pluginy np. w klasie Form, ustawiam na TRUE w metodzie group_end() (w pluginie), wywołuję metodę add_group() na klasie Form w tejże metodzie pluginu (w tym momencie pluginy wyłączone i leci dalsza część __call() czyli metoda add_group() jest wywoływana ), ustawiam zmienną $_wylacz_pluginy na FALSE i wszystko działa. Jest to rozwiązanie złe moim zdaniem, zbyt dużo trzeba pamiętać a i kod nie wygląda dobrze.

Czy jest inny sposób?
Czy to co próbuję zrobić podchodzi może pod wzorzec projektowy (którego nie potrafię znaleźć (IMG:style_emoticons/default/wink.gif) ?
Czy to da się zrobić?
Czy ktoś próbował coś podobnego wykonać?

Pozdrawiam

Ten post edytował baniczek 3.05.2012, 00:10:05
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.10.2025 - 12:55