Zend_Controller_Plugin


Dość często potrzebujemy zrobić coś przed lub po wywołaniu każdej z akcji kontrolerów, czy na przykład po zakończeniu wywoływania wszystkich akcji kontrolerów. Aby uniknąć powtarzania takiego samego kodu w wielu miejscach, możemy użyć plugina do kontrolera frontowego.

Klasa plugina rozszerza klasę abstrakcyjną. Nie musimy definiować wszystkich jej metod, możemy zdefiniować jedynie te, których chcemy użyć. Ważne jest, żeby metody które w parametrze pobierają token $action zwracały go dalej. Poszczególne metody są opisane w komentarzach. Oto szablon plugina:

PHP:
  1. <?php
  2. Zend::loadClass('Zend_Controller_Plugin_Abstract');
  3.  
  4. /**
  5. * Plugin kontrolera umożliwiający np. obsługę layoutów,
  6. * proxy itp.
  7. *
  8. * Przykładowo możemy dzięki niemu zapobieć powtarzaniu
  9. * kodu w każdym kontrolerze.
  10. */
  11. class Foo_Controller_Plugin_Layout extends Zend_Controller_Plugin_Abstract
  12. {
  13. /**
  14. * Metoda wywoływana przed rozpoczęciem procesu routingu.
  15. */
  16. public function routeStartup()
  17. {}
  18.  
  19. /**
  20. * Metoda wywoływana po zakończeniu procesu routingu.
  21. */
  22. public function routeShutdown($action)
  23. {
  24. return $action;
  25. }
  26.  
  27. /**
  28. * Metoda wywoływana przed rozpoczęciem procesu
  29. * dispatchingu.
  30. */
  31. public function dispatchLoopStartup($action)
  32. {
  33. return $action;
  34. }
  35.  
  36. /**
  37. * Metoda wywoływana przed każdym wywołaniem kontrolera.
  38. */
  39. public function preDispatch($action)
  40. {
  41. return $action;
  42. }
  43.  
  44. /**
  45. * Metoda wywoływana po każdym wywołaniu kontrolera.
  46. */
  47. public function postDispatch($action)
  48. {
  49. return $action;
  50. }
  51.  
  52. /**
  53. * Metoda wywoływana tylko raz, po wywołaniu wszystkich
  54. * kontrolerów.
  55. */
  56. public function dispatchLoopShutdown()
  57. {
  58.     // tu akurat wyciągamy obiekt widoku z rejestru
  59.     // i wyświetlamy stronę na podstawie szablonu
  60.    
  61.     $view = Zend::registry('view');
  62.     echo $view->render('layout.php');
  63. }
  64. }
  65.  
  66. ?>

Plik plugina powinien być umieszczony w podobnej strukturze katalogów jaka jest używana w frameworku, z tą różnicą, że nasz zestaw klas powinien mieć inną nazwę głównego katalogu (w tym przypadku Foo). Powinno to wyglądać w ten sposób:

Zend
  Cache
  Config
  ...
Foo
  Controller
    Plugin
      Layout.php

Teraz jedyne co zostało to zarejestrowanie plugina w kontrolerze frontowym w pliku ładującym (bootstrap), którym najczęściej jest index.php:

PHP:
  1. <?php
  2. $controller = Zend_Controller_Front::getInstance();
  3. $controller -> registerPlugin(new Foo_Controller_Plugin_Layout());
  4. ?>

Oczywiście obie klasy (Zend_Controller_Front i Foo_Controller_Plugin_Layout) powinny być wcześniej załadowane. Można to zrobić ręcznie:

PHP:
  1. <?php
  2. Zend::loadClass('Zend_Controller_Front');
  3. Zend::loadClass('Foo_Controller_Plugin_Layout');
  4. ?>

lub zdefiniować w pliku ładującym funkcję __autoload:

PHP:
  1. <?php
  2. function __autoload($class) {
  3.     Zend::loadClass($class);
  4. }
  5. ?>

Oczywiście trzeba pamiętać, że plugin zadziała globalnie, czyli dla wszystkich akcji kontrolerów wywoływanych przez daną instancję kontrolera frontowego. Jeśli chcemy zrobić coś tylko dla akcji z konkretnego kontrolera, możemy do tego użyć konstruktora i destruktora (__construct i __destruct).

Informacje oraz linki


Inne artykuły
WYSIWYG czy WYSIWYM?
AJAX w aplikacji MVC
Polecane
Zend Studio - The premiere PHP IDE

Dodaj komentarz

Poświęć chwilę i wyraź swoją opinię. Możesz użyć niektórych znaczników HTML.

Komentarze czytelników

Wielkie dzięki za ten artykuł Wojciechu, teraz pisanie stron wizytówek jest jeszcze przyjemniejsze!!

Jeszcze jedno, zauważyłem błąd:

1. deklaracja klasy:
class Example_Controller_Plugin_Layout extends

2. tworzenie instancji obiektu:
new Foo_Controller_Plugin_Layout()

3. ładowanie pliku klasy:
Zend::loadClass(’Foo_Controller_Plugin’);

Jak dla mnie to chyba wszytsko powinno mieć jedną nazwę, a na pewno w dwóch pierwszych przypadkach, co do trezciego trzeba by to odpalić. Tak czy inaczej trzeba to chyba poprawić.

Dziękuję, obydwa błędy zostały poprawione.