Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Aplikacje PHP - Pluginy
Forum PHP.pl > Forum > PHP > Pro
Stron: 1, 2
Vengeance
Witajcie,

Były już długie dyskusje o MVC, jeszcze dłuższe o budowie jądra...
Proponuje by rozpocząc dyskusje na temat, jak w naszej aplikacji umożliwić programiście piasnie dowolnych rozszerzeń. Chodzi mi o Pluginy.

Niektóre skrypty (phpBB) rozwiązują to na zasadzie zwykłej edycji kodu,
inne (WordPress) udostępniają specjalne API. Jak Wy widzicie budowe takiego systemu?

Powiesz szczerze, że nigdy nad takim czymś nie myślałem i nie robiłem nic w tym rodzaju więc w pierwszym poscie nie opisze swojego sposobu, bo go po prostu nie mam. Licze na Waszą inwencję i na to iż temat się przyjmie :]

Czyli podsumowując:
Jak stworzyć dobre API dla Pluginów.
NuLL
Co rozumiesz jako plugin ? Uniwersalnego API dla pluginów w całej aplikacji nie napisz smile.gif
Vengeance
Dla przykładu Blog który pisze teraz...

Plugin, np:
Kalendarz,
Modyfikator BBCode dla tekstu
i inne bzdety :]
ebe
Albo w formie koszyka do cms'a przekształcający go w sklep. Tak aby user nie musiał nic robić (w sensie modyfikacji kodu) tylko kliknął sobie i doinstalował plugin. Innym przykładem jest plugin komentarzy umożliwiający komentowanie obiektów (np. artykułów, newsów) W tej chwili jeszcze nad tym nie myślę ale za kilka dni/tygodni będę miał z tym kłopot.
Ace
jedyne co mi przychodzi do glowy, to kolejka.

Dodajemy kolejne pluginy do jakiejs kolejki i uruchamiamy jeden po drugim na danych wejsciowych.

np:
wyswietlanie obiektow - plugin przechwytuje caly obiekt TRESC, i ma za zadanie zamienic bbcode na html...

chcesz uruchomic ten plugin wrzucasz odpowiadnia klase do odpowiedniego katalogu a konfigurator sprawdza czy plugin istnieje jesli tak to go automatycznie uruchamia.

Osobiscie nie korzystam z tego rozwiazania - wogole nie korzystam z pluginow, bo nie wiedzialem jak sie do tego zabrac, wiec tak tylko teoretyzuje. Mam nadizeje ze ktos przedstawi lepszy poglad na to.

lecz hm. plugin do np: komentarzy dla newsow, czy jakiegos innego typu contentu, to trzeba by bylo przechwycic zdarzenie ze wyswietla sie news, pozniej dodac do tej strony w jakis sposob formularz, a dane z formularza do jakiejs akcji trzeba przeslac po czym wrocic na poprzednia strone - trzeba by bylo stworzyc po prostu dobra klase do pluginow, ktora w sobie mialaby mozliwosc przechwycenia aktualnei uruchomionej akcji, dodania "czegos" do strony w tym wypadku formularza, oraz dodania akcji ktora ma zostac pozniej uruchomiona. Glownie caly system pluginow musialby sie opierac o funkcje dostepne w systemie, a kolejny plugin, to po prostu wykorzystanie tych funkcji.

(cala powyzsza tresc zostala napisana przed chwila, nie wdrazalem tego rozwiazania - teoria wymyslona na szybko)
treewood
W projekcie Quick.Cart wykorzystalismy takie myslenie iz pluginy powinna robic osoba, ktora sie zna na kodzie php. Ma to kilka waznych argumentow:
- aplikacja bedzie dzialac poprawnie
- aplikacja ma nie byc zwalniania zbytnio przez pluginy (czym wiecej wyjatkow itd tym gorzej)
- aplikacja ma zachowac prostote i przejzystosc kodu
- pelna automatyzacja przez (przycisniecie klawisza "instaluj plugin") nie jest najlepsza. zbyt duze ryzyko wczesniejszej zmiany kodu przez uzytkownikow

Co prawda system pluginow przemyslelismy na szybko to do tego czasu nie dokonalbym zbyt wielu jego modernizacji

U nas dziala to w taki sposob iz kazda funkcje mozna zastapic gdyz przed jej nazwa podajemy if( !function_exists( 'nazwaFunkcji' ) ).
By sprawdzic dzialanie takich pluginow wystarczy sciagnac Quick.Cart'a i popatrzec sie jak to wyglada.

W tym projekcie powstalo kilkadziesiat pluginow NIE NASZEGO autorstwa z ktorym wielu sobie bardzo dobrze radzi i nie ma wiekszych problemow z ich instalacja.

Gdybym mial gwarancje, ze kod php nie bedzie zmieniany przez innych to stworzylbym automaty, ktore same zmienialyby kod php tak by aplikacja byla jeszcze wydajniejsza bez zbednych dodatkowych wyjatkow.
treewood
dodam jeszcze to, ze gdzies tu na forum ktos kiedys pisal o wlasnym systemie pluginow. taki cos, ze w jednym pliku definiuje co sie zmienilo, co gdzie dodac, co gdzie usunac i skrypt analizujac dany plik robi zmiany.
mynio
tutaj jest coś o pluginach
http://www.phpdeveloper.org/section/tutorials/55

co prawda mało profesjonalne, ale zawsze coś

pzdr
ennics
Cytat
Gdybym mial gwarancje, ze kod php nie bedzie zmieniany przez innych to stworzylbym automaty, ktore same zmienialyby kod php tak by aplikacja byla jeszcze wydajniejsza bez zbednych dodatkowych wyjatkow.


hmm, myślę że dałoby się ten problem rozwiązać poprzez określenie interfejsu dla danych pluginów np. proste
  1. <?php
  2.  
  3. class nowyPlugin implements pluginFactory { }
  4.  
  5. ?>

interfejs pluginFactory określałby funkcje które użytkownik musi zaimplementować do swojego pluginu.
dodatkowo można ograniczyć ingerencję pluginów w nasz kod poprzez deklarację
metod które chcemy chronić jako private.
Diwi
Tak więc lekko odświeże temat. Czy komuś udało się już opracować jakiś system do obsługi wtyczek ?

Pozdrawiam
Ociu
Obejrz sobie wtyczki w dotclearze.
pozdrawiam
evo
polecam system pluginow rozwiazany w eclipse. Przejzec i przeportowac na wlasne potrzeby do php


ja pisze wlasnie teraz cos takiego a wlasciwie content manager z API do pluginow dla specializowanej zawartosci.

O co w tym chodzi:

Daje do dyspozycji strukture podzialu zawartosci plus jadra systemu z outputem (html,pdf,xml,txt). Oczekuje od pluginu udostepnienia wszystkich plikow zawarty w specyfikacji pluginow takich jak templates,config files itd.. oraz laduje plugin poprzez instanciowanie klasy o taj samej nazwie co plugin w podkatalogu znajdujacym sie w katalogu pluginow danego pluginu. winksmiley.jpg

Ta classa (ten objekt) musi byc dziedziczona od mojego Interfaceu CMPlugin ktory daje nam funkcje do operacji takich jak przeszukiwanie , edytowanie,usuwanie,dodawanie oraz wyswietlanie zawartosci.

Projekt musze napisac do 17 Stycznia, wiec mysle ze po tej dacie udostepnie go.



Pozdrawiam
evo
Ociu
Ja myśle, że nie będe używał żadnych BBCode (taką przynajmniej mam nadzieje), dlatego u mnie wszystko działa metodą łańcuchową, a system uruchamia się poprzez:
  1. <?php
  2. $CORE->systemStart( new Application(), new HttpRouter(new HttpRequest, new HttpResponse) ); 
  3. ?>
.
Dlatego myśle, ze można coś zrobić tak:

  1. <?php
  2. class PluginManager {
  3. private static $map = array();
  4. public function add($plugin, $parametr = false) {
  5. self::$map[$plugin] = ($parametr === false) ? $plugin : $parametr;
  6. }
  7.  
  8. public function loadAll() {
  9. foreach(self::$map AS $plugin => $parametr) {
  10. if($plugin == $parametr) {
  11. $pl = new $plugin();
  12. } else {
  13. $pl = new $plugin($parametr);
  14. }
  15. }
  16. }
  17. ?>


Myśle, że to najprostrze rozwiązanie jakie może być i do tego dobre winksmiley.jpg
pozdrawiam
bela
Ociu, ok, ale załadowałeś i co teraz zrobisz? Jak wpłyniesz na kształt czegoś?
Ociu
Przed chwilą prześmyślałem to co napisałem i stwierdzam, że kod działa, ale jako loader załadowanie. Aby plugin był użyteczny, trzeba ingerować w kod klas.

Jak narazie to nie mam pomysłu.
ActivePlayer
do tego dochodzą jeszcze zaleznosci... bo mamy np. plugin komentarzy obiektow, i plugin bb codu... ale jako 2 osobne... jesli plugin komentarzy nie jest zainstalowany, to nie pokazujemy bb code w komentarzach, w przeciwnym wypadku pokazujemy. do tego przydalo by sie jakos konfigurowac, bo przeciez ktos moze nie chcec bb code w komentach, tylko np. w samych newsach czy gdziekolwiek indziej...
Degregar
Pracuję właśnie nad framework'iem, w którym mam zamiar uwzględnić system ładowania pluginów.
W poprzednim CMSie plugin'em była po prostu klasa w jakimś module. Ale teraz dochodzę do wniosku, że poszerzę system katalogów modułu (wcześniej module/action) do module/submodule/action i jeden moduł będzie nosił nazwę 'plugins', gdzie będę mógł załadować potrzebne mi pluginy.
Potem tylko w edytorze template'a wpisuję odpowiednią linijkę ( np. <plugin>kalendarz</plugin> ), zmiany zapisywane są w pliku konfiguracyjnym i poprzez filtry (w moim przypadku services) sprawdzam w configu, czy do danego template'a jest przypisany jakiś plugin, dodaję do łańcucha akcji i tyle.
PluginManager również można tutaj wykorzystać zamiast np. action chain.

Generalnie możliwości jest sporo, wszystko zależy od budowy aplikacji. Nie ma jakiegoś uniwersalnego sposobu.

Co do zmiany bbcode na html, to najlepiej na filtrach (jeśli mowa o MVC przede wszystkim) - przed wykonaniem akcji sprawdzamy w konfigu, czy dana akcja ma być filtrowana (bbcode na html), jeśli tak, to po wykonaniu akcji pobieramy wynik kodu i filtrujemy.
seaquest
A ja myślę, że trzeba trochę połączyć wszystkie te rozwiązania. Bardzo dobrym pomysłem wydaje mi się kolejka. To bardzo dobre rozwiązanie. Problem pojawia się jednak, gdy kilka pluginów dotyczy jednego rodzaju treści.
Ja bym zrobił tak. Jedną obiekt klasy Content, który będzie przechowywał dane wyciągnięte z bazy. Później zakładamy kolejkę, w której umieszczamy najpierw klasę odpowiadającą za podstawowe interpretowanie treści, a następnie kolejne pluginy (powiedzmy według przypisanej im wagi, bo to też czasem ważne). Później kolejno wywołujemy jakąś metodę (tak samo nazwaną we wszystkich klasach).
Konkludując. Potraktujmy podstawowe opracowywanie treści jako plugin o najwyższej wadze!
Co wy na to?
Ace
hm, mysle ze to jest sensowne, ale w chwili obecnej rozmyslalismy o pluginie ktory bedzie pelnil funkcje filtru na jakis content.

Co w wypadku gdy chcemy dograc plugin do koszyka ktory nam umozliwi platnosci online, chodz moze ograniczmy problem do dodawania nowych form platnosci. Wiec - mamy w systemie powiedzmy cos co pelni funkcje platnosci i mamy mozliwosc dogrywania w bardzo prosty sposob nowych form platnosci.

Jak to zrealizowac? Tez kolejka w ktorej bedziemy mieli liste platnosci, wybierzemy jedna, to uruchomimy odpowiednia klase, a wniej odpowiednie metody? Jak to sobie wyobrazacie?

Mysle ze warto by bylo omowic kilka takich problemow.

Pozdrawiam
Vengeance
A co jeśli chcemy napisać plugin do pluginu będącego pluginem innego pluginu naszej aplikacji? snitch.gif rotfl!
Ociu
Cytat(Vengeance @ 2005-11-22 16:37:41)
A co jeśli chcemy napisać plugin do pluginu będącego pluginem innego pluginu naszej aplikacji? snitch.gif rotfl!

To wtedy trudniamy sobie życie laugh.gif

Pisząc PluginManager stweirdziłem, że najlepiej będzie zrobić sam loader.
  1. <?php
  2. Class PluginLoader {
  3. private $map = array();
  4. public $loaded = array();
  5.  
  6. public function add($plugin, $parametr = false) {
  7.  if($parametr == false) {
  8. $this->map[$plugin] = $plugin;
  9.  }else{
  10. $this->map[$plugin] = $parametr;
  11.  }
  12. }
  13.  
  14. public function load() {
  15. foreach($this->map AS $plugin => $parametr) {
  16. if($plugin == $parametr) {
  17. $this->loaded[$plugin] = new $plugin();
  18. } else {
  19. $this->loaded[$plugin] = new $plugin($parametr);
  20. }
  21. }
  22. $this->map = array();
  23. }
  24. }
  25. }
  26. ?>


Można to użyć tak:
  1. <?php
  2. $PluginLoader = new PluginLoader();
  3. $PluginLoader->add('Application');
  4. $PluginLoader->load();
  5. foreach($PluginLoader->loaded AS $name => $value) {
  6. $$name = $value;
  7. }
  8. ?>

Kod troszke badziewny, pisany z palca. Jak anrazie działa, będe go przebudowywał.
PS. Pisząc ten post, pomyślałem o tym, że można by zamieszać w to iteratory winksmiley.jpg
LBO
Cytat(Vengeance @ 2005-11-22 14:37:41)
A co jeśli chcemy napisać plugin do pluginu będącego pluginem innego pluginu naszej aplikacji? snitch.gif rotfl!

wydaje mi sie ze trzeba stworzyc jeszcze klase (lub zaimplementowac w loaderze) kontrole zaleznosci... czyli np. plugin daje komunikat o braku potrzebnej mu do dzialania klasy stopuje skrypt... lub nie laduje sie wcale i wpisuje blad do logów.. no czy cos w tym rodzaju
Ociu
A co jeśli pluginem jest wybieraniem odpowiedniej bazy danych ? Stopujesz go i cały system pada.

pozdrawiam
sztosz
Cytat(Vengeance @ 2005-11-22 16:37:41)
A co jeśli chcemy napisać plugin do pluginu będącego pluginem innego pluginu naszej aplikacji? snitch.gif rotfl!

Tutaj chyba taki pattern jak Decorator by dał radę.

Moim zdaniem nie da się zaimplentowac jakiegoś generalnego API dla pluginów.

Jeden moduł służący jako kontroller pluginów który nie pozwoli m.in używać dwóch różnyych pluginów robiących to samo ale w inny sposób.

+

Bardzo przejzysty kod (oczywiście wszystko obiektowo) z bardzo jasnym rozdzieleniem częsci protected od private każdej klasy.

+

Pluginy jako rozszerzenia danych klas (extends) zastepujące dane klasy (ichh funkcje w kodzie i wywołania)

ALBO (co jest chyba ciekawsze)

Plugin jako Decorator tylko że ttu z implentacją będzie bardzo trudno sad.gif
NuLL
Ja pluginy w swoich aplikacjach rozwiazuje w inny, okreslony sposob i ktory dziala, nie bedac abstrakcja programistyczna biggrin.gif

Mam w kodzie aplikacji miejsca uruchamiajace pluginy owszem nie moge ich miec w dowolnym miejscu kodu. Ale np uruchamiajac plugin koszyka moge z katalogu produktow zrobic pseudosklep - w sam plugin jest uruchamiany w dwoch miejscach. Kod html jest umieszczony dzieki komentarzom zawartym w danym templacie i prostemu str_ireplace. Ot cała filozofia smile.gif
LBO
Cytat(Ociu @ 2005-12-27 20:08:39)
A co jeśli pluginem jest wybieraniem odpowiedniej bazy danych ? Stopujesz go i cały system pada.

heeh, zakladam podzial aplikacji na elementy CORE i dodatkowe (rozszerzenia funkcjonalnosci)... wtedy mozna sie pobawic w sposob dwojaki: dla elementow CORE zrobic dla pluginow API, dla rozszerzen loader'a... w sumie nie bawilem sie w pluginy (chociaz nagminnie stosuje loadery baz danych factory patternem, a to mozna juz nazwac pluginami)...
em1X
Uniwersalnego sposobu mysle nie ma. Ostatnio robilem serwis, ktory w oryginale byl goły... jednak w miare dodawania pluginow jego funkcjonalnosc sie rozszerzala: dodaj zdjecie, wiadomosci prywatne, i tak dalej...

Za najprostsze rozwiazanie uznalem stworzenie abstrakcyjnej klasy Plugin, klasy PluginManager ładujacej pluginy.

Ogolnie rzecz biorac przydaly sie wzorce projektowe Factory oraz Strategy. Zabawa przednia po prostu super smile.gif milo, gdy programowanie sprawia przyjemnosc programiscie..
nasty
Mi sie udalo napisac system do obsugi pluginow w moim programie nad ktorym kiedys pracowalem
Ale jest jedna sprawa, niema uniwersalnej metody obsugi pluginow, bo w kazdym systemie pluginy sa do czegos innego, ale tak bardzo ogulnie jest jedan metoda:

zrobic tabele w bazie danych ktura przechowuje adres guwnego pliku z pluginem (php), i gowne class pluginu
oraz funkecje Main()

w ten sposow program bedzie includowal plik z pluginem, (ale ten plik niczego nie robu przed wywolaniem funkcji Main()), i wykona :
  1. <?php
  2. $classname = // nazwa klasy plugina;
  3.  
  4. call_user_func(array($classname, 'Main'));
  5. ?>


w ten sposob mozna zrobic pluginy, aha i klasy w tym przypadku maja za zadanie wyruzniac pluginy, bo wszyskie beda wywolywac funckje Main.
Ociu
Myślę, że ta metoda nadaje się lepiej do flitrów niż do pluginów.

IMHO, filtry, to klasy, które muszą mieć metodę o danej nazwie, main, execute, perform etc. która jest wykonywana. Można narzucić tą metodę ( interfejsy i te sprawy ). Działała to na zasadzie użyj i zapomnij.
Pluginy, to klasy, które nie są czymś ograniczone, to klasy (można oczywiście to zrobić, to zależy od piszącego), które poprostu są dodatkami, np. BlockController, mamy do nich dostęp cały czas.

  1. <?php
  2. class PluginManager{
  3. protected $pluginsMap = array();
  4.  
  5. public function __get( $sPluginName ) {
  6. if(isset($this->pluginsMap[$sPluginName])) {
  7. return $this->pluginsMap[$sPluginName];
  8. } else {
  9. throw new Exception('Plugin . ' $sPluginName ' . not found');
  10. }
  11. }
  12. }
  13. ?>


Przez co możemy odwoływać się do pluginu w każdym miejscu w skrypcie.
erix
ja robie w ten sposob:
Dajmy na to jest klasa $module, ktora jest baza dla wszystkich wtyczek (wtyczki ja extendsuja).

Do tego jest cos takiego jak kontroler modulow. W pliku startowym jest on inicjowany, includuje wlaczone wtyczki (globalna tablica z nazwami), tworzy odwolania w tablicy (jedna wtyczka = jeden element). Potem jest ona odpytywana ($wtyczka->init()), zeby sobie mogla poustawiac zmienne itp. (moglem dodac sprawdzanie, czy wtyczka jest na 100% do mojego systemu, ale pisze wtyczki tylko ja, to mi nie trzeba bylo biggrin.gif).

Potem (po inicjowaniu) odpalam metody run(), aby mogly sie zainicjowac niejako na drugim etapie (gdy sa zaleznosci pomiedzy modulami, np. wtyczka od sql).

Na dobranoc jest shutdown(); zapisuje dane, itp.

Pisane pod PHP4, proste, niezawodne i (biggrin.gif) dzialajace.
NuLL
Ktos korzysta z wlasnych silnikow pluginowych w waszych dzialajacych ( nie eksperymentalnych ) projektach questionmark.gif Patrzac na to co piszesz tutaj jestescie bardzo pracowici i kazdy z pomyslow wymaga duzo kodu by cokolwiek wlaczyc :|
g00fy
mi podoba sie polaczenie Visitora z Componentem. lub jesli ktos chce to Observator.
NuLL
Cytat
mi podoba sie polaczenie Visitora z Componentem. lub jesli ktos chce to Observator.

Cokolwiek to znaczy.

A ktos moze przygladal api pluginowemu Wordpressa questionmark.gif Wg mnie kawal dobrego kodu i pomyslu smile.gif
anas
Hej.

Myślę że tutaj z pomocą może przyjść Pico Container (Java) i port do php. Chyba Paweł Kozłowski z Supermedia to pisał. Samo rozszerzanie może bez problemu odbywać się na zasadzie wykorzystania wzorca Decorator - problem był w centralizowaniu dodawania(wstrzykiwania) w łancuch tworzenia zależności między obiektami właśnie tego plugin'u który nam potrzebny i rozszerzenia obiektu powyżej - Pico może to rozwiązać, ale narazie poza przeczytaniem ogólników nic więcej nie mogę powiedzieć, będę to testował - jak dojde do czegoś logicznego to napiszę.

pozdrowka
UDAT
Ostatnio zastanawiam nad użyciem AOP w celu uzyskania funckjonalności pluginów.

W ten sposób bardzo prosto można dodać/tworzyć dowolne pluginy.

Przykład1: Plugin autoryzacji
  1. <?php
  2. aspect Security{
  3. pointcut modelConstruction:new(IModel(*));
  4. pointcut modelExecution:exec(public IModel+::*(*));
  5.  
  6. around(): (modelExecution || modelConstruction){
  7. //Przeprowadź autoryzację
  8. }
  9. }
  10. ?>


Przykład1: Plugin BBCode do artykółów
  1. <?php
  2. aspect BBCodePlugin{
  3. pointcut setArticleBody:exec(public Article::setBody(2));
  4.  
  5. after($body): setArticleBody{
  6. return BBCodeParser::parseText ( $body );
  7. }
  8. }
  9. ?>


W ten sam sposób można dodać najprzeróżniejsze pluginy, a nawet pluginy pluginów pluginów....


Zalety:
+ można dodać prawie każdy możliwy plugin
+ zero przygotowań kodu / 0 nadmiarowych linii kodu
+ może współistnieć z innym systemem pluginów
+ odnosimy korzyści z użycia AOP ( poprawa modularności, itp. )
+ można dać pluginy/filtry na np. konstrukcję obiektów/ustawienie właściwości co w normalnym podejściu byłoby trudne
+ można połączyć łatwo z PicoContainer'em ( nałożyć pointcut'a na tworzenie obiektów )
Wady:
- pomocna jest dobrze zaplanowana architektura ( drobne, krótkie metody, używanie interfejsów, itp. )
- narazie AOP dla PHP jest w powijakach ( nie jest jednak fatalnie )
- dodatkowa faza wdrażania - weaving ( jedno zadanie Phing'a/Make'a itp. załatwia sprawę )
- wymaga zaznajomienia się z AOP

Linki:
* PHPAspect
* PHP AOP
* AspectJ ( pierwowzór wszystkich implementacji AOP )
webik
Witam

Cytat(anas @ 28.06.2006, 11:08:19 ) *
Myślę że tutaj z pomocą może przyjść Pico Container (Java) i port do php


Jestem takiego zamego zdania, tylko ja napisalem swoj wlasny Container... z wsparciem dla wzorca Decorator... Na razie go tetuje ale testy wpypadaja obiecujaco, moze nie ma takiego uniwersalizmu i takich mozliwosci jak Pico ale mysle ze w miare rozwoju to dogonie Pico biggrin.gif ...

Wg mnie to najlepsze rozwiazanie....

Pozdrawiam
darektbg
W Rapide jest to ciekawie zrobione, możliwe są cztery rodzaje pluginów:

1. Przed uruchomieniem procesu wykonywania akcji
2. Przed wykonaniem każdej akcji
3. Po wykonaniu każdej akcji
4. Po zakonczeniu uruchamiania akcji

Załodowanie konkretnego pluginu:
  1. <?php
  2. $oFront->registerPlugin(new Rapide_Controller_Front_Plugin_ACL);
  3. ?>


W tym przypadu akurat plugin ACL, korzysta z metody preExecution(wykonywana przed wywołanie konkretnej akcji):
  1. <?php
  2. class Rapide_Controller_Front_Plugin_ACL extends Rapide_Controller_Front_Plugin
  3. {
  4. public function preExecution(Rapide_Dispatcher_Token_Interface $oToken)
  5. {
  6.  // operacje wykonywane przez plugin
  7. return $oToken;
  8. }
  9. }
  10. ?>
Strzałek
Hola, hola, powoli. Ale to co pokazałeś z Rapide to raczej Filtry i implementacja Intercepting Filter. W temacie chodzi o coś innego, przeczytaj jeszcze raz od początku.

Za pomocą czegoś takiego nie da się zrobić pluginu tylko filtr!

To mała różnica winksmiley.jpg
Athlan
Imho @nasty_psycho już dobrze kombinuje:
http://forum.php.pl/index.php?s=&showt...st&p=260817
NuLL podał dobry przykład Wordpressa, jednakże pluginy sa jedynie ładowane a przy większej organizacji danych trzeba funkcje do templata wstrzykiwac samemu. Drobna uwaga to to, że dobrze jest to zrobione, że opcje same dodają się do górnego menu (super).

Cytat
Hola, hola, powoli. Ale to co pokazałeś z Rapide to raczej Filtry i implementacja Intercepting Filter. W temacie chodzi o coś innego, przeczytaj jeszcze raz od początku.


Strzałek, nie patrz teraz pod kątem co to jest i jak ładowane, ale jak to wykorzystujemy. Możemy zrobić sobie plugin, który będzie integrował w tablice $_GET i $_POST, który wykryje włączone/wyłączone magic quotes i wykona odpowiednie kroi przed executem jakiegokolwiek kontrolera.

Odbiegając od filozofii... pojawił się tutaj post, w którym został poruszony problem dajmy na to bbcode w odpowiednich miejscach aplikacji, np w treści newsa, ale w komentarzach już nie. Nie jestem pewnien, czy możliwy jest superelastyczny sposób, aby przefiltrować takie dane. Jeżeli chceilibyśmy sprawdzac czy istnieje ewentalny plugin do załóżmy obiektu newsa. Każdny news potraktujmy jako obiekt:

  1. <?php
  2. $oNews = new News('id');
  3. $oNews->loadPlugins();
  4. echo $oNews->data->title;
  5. echo $oNews->data->text;
  6. ?>


sprawdzimy czy jest plugin do przefiltrowania tytułu newsa i podejmiemy odpowiednie ktoki, jednaże w treści bbcode by nie został użyty. Wydłuża się tutaj czas działania apliacji o więcej niż "troszkę". Tak jak to było powiediane wcześniej, nie ma uniwersalnego API do ładowania pluginów.

Moim zdaniem ZAWSZE będzie potrzebna ingerencja programisty, chociażmy tak:

  1. <?php
  2. $oBBCode = $oPlugin->load('bbcode');
  3. $oBBCode->parse($oNews->title);
  4. ?>
LBO
Cytat(Strzałek @ 2.04.2007, 15:21:08 ) *
Hola, hola, powoli. Ale to co pokazałeś z Rapide to raczej Filtry i implementacja Intercepting Filter. W temacie chodzi o coś innego, przeczytaj jeszcze raz od początku.

Za pomocą czegoś takiego nie da się zrobić pluginu tylko filtr!

To mała różnica winksmiley.jpg


W dodatku to jest jeszcze okrojona wersja filtrów z Zend Framework.
Zeman
To ja też wtrące swoje 0,03 PLN.

Na początek napiszę że moje rozumowanie pluginów wzięło się z pisania w Delphi aplikacji będących serwerami COM. Także moje poniższe rozważania trochę są ukierunkowane w stronę COM aniżeli w stronę PHP winksmiley.jpg takie zboczenie zawodowe.

Przede wszystkim należy sobie zdać sprawę że są różne rodzaje pluginów - pluginy ogólnego przeznaczenia i pluginy dedykowane jakiejś funkcjonalności. Te pierwsze jest dużo trudniej wprowadzić w życie.
Projektując system pluginów najpierw sobie musimy zadać pytanie do czego mają być te pluginy. Powiedzmy, że zbudowaliśmy jakiś system i chcemy dać możliwość rozbudowy go poprzez pluginy. Po pierwsze, najlepiej zabronić grzebania w kodzie głównym, gdyż to będzie powodowało destabilizacje pozostałych pluginów. Możemy kod główny, np klasy opatrzeć np w interfejsy i nakazać, żeby plugin korzystał tylko z tychże interfejsów. Warto uzewnętrznić zdarzenia np. w klasie TUser zdarzenia onLogin(...) onLogout(...) onRegister itd. W projekcie niech będzie powiedzmy singleton manager pluginów i taki taki singleton ma mieć dostęp do wszelkich instancji klas kodu głównego, czyli np Manager ma mieć dostęp do obiektu $user klasy TUser. Ponadto, każda instancja pluginu ma się zgłaszać do managera że się powołuje do życia.
Należy też wymyśleć i zdefiniować czym jest plugin, przykładowo plugin to jest obiekt takiej klasy, która implementuje interfejs IPlugin. Interfejs ten niech ma metody pozwalające sterować się managerowi. Manager przyjmował będzie zgłoszenia tworzenia nowych pluginów i będzie je dodawał do swojej listy, jednocześnie będzie miał możliwość coś zrobienia z każdym takim pluginem dzięki interfejsowi IPlugin.

Przykład:
Memy manager będący singletonem TPManager,
mamy obiekt użytkownika typu TUser.
Obiekt użytkownika udostępnia zdarzenie onLogin(..).
Manager ma pole $user, czyli np. TPManager::instance()->user;
Niech interfejs IPlugin ma metodę doOnRegister(..)

Tworzony jest obiekt - plugin, mający na celu jakąś reakcję na zalogowanie się, powiedzmy sprawdza czy user ma nowe wiadomości i je wyrzuca na ekran. Taki tworzony plugin zgłasza się do managera, manager go rejestruje na swojej liście. Dodatkowo, manager po dodaniu pluginu na listę wywołuje jego metodę doOnRegister(...), a ta metoda, odwołuje się poprzez manager do obiektu usera i rejestruje w nim swoje zdarzenie onLogin.
Teraz powiedzmy, że użytkownik się loguje, zatem wywoływana zostaje metoda powiedzmy TPManager::instance()->user->tryLogin(..). W tej metodzie jest kod logujący i w przypadku udanego logowania wywołuje $this->onLogin(). $this->onLogin wywołuje wszystkie zarejestrowane u siebie zdarzenia, czyli wywołuje zdarzenie z podłączonego pluginu, a to już sprawdza czy są nowe wiadomości i w razie czego wali je na ekran.

Ale natłukłem tekstu, ciekawe czy komuś będzie sie chciało tyle czytac winksmiley.jpg

Pozwiodronka,
Zeman.

Dodam że sam nie korzystam z tego co opisałem winksmiley.jpg Pluginowość załatwia mi plugin dyrektyw w moim edytorze PHP, tylko sobie klikam checkboxy które pluginy a właściwie moduły chce mieć w danym projekcie i ten mi wypluwa kod PHP okrojony z pozostałych pluginów, coś w rodzaju (na podstawie poprzedniego przykładu):
  1. <?php
  2. class TUser {
  3. function tryLogin() {
  4.  ... // logowanie
  5.  {$IFDEF "modul_sprawdzania_wiadomosci"}
  6. ... // kod do sprawdzania wiadomości
  7.  {$ENDIF}
  8. }
  9. }
  10. ?>


Pozwiodronka,
Zeman.
Athlan
Cytat
Ale natłukłem tekstu, ciekawe czy komuś będzie sie chciało tyle czytac


Przeczytałem bardzo dokładnie i pozwolę sobie dokonać analizy.

W Twoim przypadku wykonujesz jakieś pluginy przed wykonaniem metody lub/i po niej. Np Login() => onLogin() (podobnie do JavaScriptu). Pomysł bardzo dobry, wręcz genialny, ale sprawdzanie, czy metoda istnieje za kazdym razem spowolni zleksza aplkiacje hm?

Ok do rzeczy. Tak jak przedstawiłem w moim poprzednim poście, przyczepmy się tego naszego BBCode. Trzeba jakoś treść newsa przepóścić przez metodę BBCode::Parse() a jest to niezbędne albo w kontrolerze, albo w templacie. Nie chcemy tutaj ingerować w kod aplikacji. Dzięki rozwiązaniu Zeman'a możemy zrobić tak, że obiekt widoku jest trzymany jako argument kontrolera, przez co jest w stanie używalności przez cały czas. Do czego zmierzam. Kolejność wykonywania poszczególnych metod:

$oController->preLogin(metoda_pluginu_jakiegos); // wykonamy PRZED kontrolerem Login
$oController->outLogin(metoda_pluginu_jakiegos); // wykonamy tuż przed executem widoku w kontrolerze przez dispatcher, ale po wykonaniu wszelkich akcji wewnątrz kontrolera
$oView = $oController->Login(); // każdy kontroler zwraca obiekt widoku;
$oView->display(); // no i execute

W czym rzecz... metoda outLogin() wykonana zostanie po wszelkich działaniach kontrolera, ale jeszcze przed wyrzuceniem (return) widoku, co pozwoli nam na dowolną ingerencję w kontroler zaraz po wykonaniu operacji. W naszym przypadku (BBCode) filtrujemy sobie jeden argument z idoku przechowywanym jako argument kontrolera:

  1. <?php
  2. outLogin()
  3. {
  4. $this->LoadPlugin('BBcode');
  5.  
  6. $this->oView->news_content = BBCode::Parse($this->oView->news_content); // bbcode
  7. $this->oView->news_content_long = BBCode::Smileys($this->oView->news_content); // emotikony w dlugiej czesci newsa
  8. }
  9. ?>


To by było na tyle z mojej strony, ciekawe czy ktoś przeczyta smile.gif

Cytat
Pozwiodronka,
Zeman.


Zdraviam smile.gif
Zeman
Cytat(Athlan @ 6.04.2007, 09:34:47 ) *
To by było na tyle z mojej strony, ciekawe czy ktoś przeczyta smile.gif


Przeczytałem, ale wiele z tego nie rozumiem, może dlatego, że nie znam BBCode. W moim rozumowaniu pluginów bardziej to podchodzi pod "pluginy dedykowane" o których wspomniałem w podziale pluginów ale ich nie opisywałem. A może się pokuszę o napisanie mikro-artykułu winksmiley.jpg Tylko czy ktoś to będzie czytał...
faster
Cytat
Tylko czy ktoś to będzie czytał...


Witam,
... czytam, czytam ... dokładnie i sam się zastanawiam jak podejść do tematu.
Zgadzam się na pewno z jednym, pluginy to rozszerzenia funkcji systemu zatem trzeba najpierw zaplanować co chcemy aby było rozszerzane. Słyszałem o systemach które są ponoć całkowicie rozszerzalne i można pisać pluginy do wszystkiego ale czy to przypadkiem nie polega na przepisywaniu czy modyfikacji istniejącego już w systemie kodu? Bo nie potrafię sobie wyobrazić jak można rozszerzyć wszystko smile.gif w aplikacji.
Zastanawia mnie natomiast jeszcze inna rzecz .... jak trzeba zaprojektować genialnie aplikację aby była tak rozszerzalna jak firefox smile.gif co Wy na to?

Pozdrawiam
::faster
Zeman
Cytat(faster @ 15.04.2007, 23:44:14 ) *
Witam,
... czytam, czytam ... dokładnie i sam się zastanawiam jak podejść do tematu.
Zgadzam się na pewno z jednym, pluginy to rozszerzenia funkcji systemu zatem trzeba najpierw zaplanować co chcemy aby było rozszerzane. Słyszałem o systemach które są ponoć całkowicie rozszerzalne i można pisać pluginy do wszystkiego ale czy to przypadkiem nie polega na przepisywaniu czy modyfikacji istniejącego już w systemie kodu? Bo nie potrafię sobie wyobrazić jak można rozszerzyć wszystko smile.gif w aplikacji.
Zastanawia mnie natomiast jeszcze inna rzecz .... jak trzeba zaprojektować genialnie aplikację aby była tak rozszerzalna jak firefox smile.gif co Wy na to?

Pozdrawiam
::faster



Aplikacje typu FF sa serwerami COM'opodobnymi, które udostępniają na zewnątrz kupę interfejsów. Pisząc plugin pisze się tak naprawdę aplikację kliencką która wykorzystuje te uzewnętrznione interfejsy żeby coś na nich robić. Jak można się domyślać FF ma swoje wewnętrzne obiekty, te obiekty implementują interfejsy. Interfejsy są "przedefiniowane" na tzn język IDL, który stanowi jakby pomost pomiędzy różnymi językami - IDL stanowi standard opisywania interfejsów. Aplikacje - pluginy z grubsza powiedziawszy odczytują definicje interfejsów z tego IDLa i przedefiniowują je na język w którym jest pisany plugin. Najczęściej języki wspierają tworzenie tzw wrapperów. Z punktu widzenia autora pluginu wrapper to obiekt będący klonem obiektu w aplikacji serwera, czyli np jeśli FF ma obiekt powiedzmy Document, to w pluginie też istnieje obiekt Document o tych samych metodach, jednak w pluginie obiekt ten jest wrapperem na obiekt w FF - czyli jeśli plugin wywoła Document->metoda(), to tak naprawdę wywoła się metoda() ale w FF. FF z tego co mi wiadomo wykorzystuje XPCOM i jest to technologia podobna do COM i CORBA, tyle że cross-platform. COM nie jest cross-platform.
Suma sumarum wlaśnie tak się robi aplikacje typu FF - odrazu się zakłada że aplikacja będzie serwerem COM i wszystkim nowo tworzonym klasom nadaje się cechę bycia obiektem COM, co jest równoznaczne z tym, że klasa będzie udostępniała na zewnątrz interfejsy do języka IDL. Dalej się nie będę rozwodził na ten temat ale jest to dosyć trudne zagadnienie no i to forum jest o PHP a wątek dotyczy pluginów w PHP a nie pluginów w FF winksmiley.jpg
yaotzin
Witam nie przeczytałem wszystkich postów bo nie mam czasu teraz i moze sie powtórzę smile.gif Ale chciałbym zauważyć wiele stron internetowych jest postawionych na czymś takim jak joomla! W joomla aby rozszerzyć możliwości tego framework'a wystarczy doinstalować nowe moduły lub komponenty, jako że pierwsze rozszerzają tylko funkcjonalność serwisu i nie wnoszą nowych modyfikacji, to te drugie w oparciu o API Joomla w dużym stopniu zmieniają działanie seriwsu i to co widzi użytkownik na stronie. Działanie tego elementu w joomla jest niemalże niezawodne, i sprawuje się doskonale, zapewne ma jakieś ograniczenia, ale wydaje mi się że implementowanie czegoś takiego jak moduły w joomla! jest w sumie dosyć proste i chcę taką rzecz za jakiś czas robić (oczywiście przy wolnej chwili), mam nadzieję że się uda.
Kasjan
witam, przepraszam ze odkopuje stare tematy, ale ten byl akurat na pierwszej stronie, a jego temat jest bardzo interesujacy.
mysle ze mozna bez problemu zorganizowac pluginy jednak trzymajac sie pewnego zalozenia: tworzymy swoj wlasny cms, i odgornie narzucamy mu konkretna strukture. tak np. modul news bedzie dzialal na zasadzie klasy, bedzie posiadal metody
- newsEdit
- newsDelete
- newsAdd
- newsDisplay
i tak, wewnatrz kazdej metody
Kod
public newsAdd() {
plugins::before('newsAdd');
// tutaj kod wlasciwy funkcji
plugins::after('newsAdd');
}


skad brac pluginy? funkcja plugins::after i plugins::before automatycznie przechwyci nazwe uruchamianego modulu (news) i automatycznie includuje wszystkie pliki w katalogu:
/modules/news/plugins/

struktura pluginu - oczywiscie klasa, nazwijmy go sobie newsRestrictedIPs:
/modules/news/plugins/RestrictedIPs.php

Kod
class newsRestrictedIPs {
public function onNewsAdd() {
   if ($_SERVER['REMOTE_ADDR'] == '5.10.15.20') {
    ....
  }
}
}

kwestia dogrania jak do klasy news wyslac info ze ma nie wstawiac obiektu... proponuje przed plugins::before('newsAdd'); dodac $settigns = array(); a w newsRestrictedIPs::onNewsAdd dodac $settings['dontInsert'] = true;

jeszcze dwa slowa odnosnie funkcji plugins::before i plugins::after - biora katalog
modules/NAZWA_MODULU/plugins/
includuja kolejno pliki, jesli zaincluduje to sprawdza cz istnieje [mod][nazwapliku]->on[nazwaakcji] czyli np. newsRestrictedIPs->onNewsAdd i uruchamia.

oczywiscie aby to wszystko dzialalo poprawnie musimy ustalic sobie pewne regoly jak pisac - nazewnictwo klas, metod, plikow... ale sa tego plusy - mamy w aplikacji porzadek...

jakies to rozwiazanie jest - czy dobre, czy zle - wypowiedzcie sie sami.
NuLL
A co jesli chcesz operowac na jakis danych zawartych w akcji ? Pozatym pisanie za kazdym razen metod plugins::before i after to raczej marne rozwiazanie.
LBO
W większości przypadków wystarczają filtry, poparte dobrymi nawykami programistycznymi (interfejsy, dobrym dobraniem strategii etc.)
NuLL
Filtry ? To ja myslalem ze filtry sluza do czego innego blink.gif ( czyt. filtrowania ) a plugin nie zawsze tylko czysci... Pozatym nawet gdyby - jak wywolac filtr na zmiennej zawartej w akcji ?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.