ZF – Generowanie menu dla każdego modułu

Ostatnio miałem problem z menu (Zend Navigation) w mojej aplikacji modułowej. Problem polegał na tym, że każdym module było ładowane to samo menu, chociaż zdefiniowane były (nawet o innych nazwach). Szybka porada na forum php ( ;) ) i uzyskałem pewną odpowiedź z adresem do blogu forum-kolegi Batman, w którym można przeczytać:


Ładowanie wszystkich modułów podczas inicjalizacji aplikacji.

Jest to jeden z największych problemów podczas korzystania z modułów.

 

Napisał także gotowe rozwiązanie, niestety w moim przypadku nie chciało do końca działać. W związku z tym zacząłem szukać innego rozwiązania…

Znalazłem rozwiązanie wykorzystujące plik XML. W związku z tym trzeba było wykonać mały przerób i rozwiązanie działa :)

Rozwiązanie:

Moja struktura katalogu odpowiadająca za moduły (podświetlone pliki z menu):

  1. \---modules
  2. +---admin
  3. | | Bootstrap.php
  4. | | menu_admin.php
  5. | |
  6. | +---controllers
  7. | +---forms
  8. | +---models
  9. | \---views
  10. |
  11. +---default
  12. | | Bootstrap.php
  13. | |
  14. | +---controllers
  15. | +---models
  16. | \---views
  17. |
  18. +---professor
  19. | | Bootstrap.php
  20. | | menu_professor.php
  21. | |
  22. | +---controllers
  23. | +---forms
  24. | +---models
  25. | \---views
  26. |
  27. \---student
  28. | Bootstrap.php
  29. | menu_student.php
  30. |
  31. +---controllers
  32. +---forms
  33. +---models
  34. \---views

Pliki odpowiadające za menu mają nazwę: menu_nazwa_modulu np: menu_student . Teraz należy dodać plugin, który znalazłem wraz z moją przeróbką na odczyt z plików PHP:

  1. <?php class Plugins_ModuleNavigation extends Zend_Controller_Plugin_Abstract {
  2.  
  3. public function preDispatch (Zend_Controller_Request_Abstract $request)
  4. {
  5. $module = $request->getModuleName();
  6. if(empty($module)) $module = "default";
  7. $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  8. $viewRenderer->initView();
  9. $view = $viewRenderer->view;
  10.  
  11. if($module != 'default') {
  12. $config = require APPLICATION_PATH . '/modules/'.strtolower($module).'/menu_'.strtolower($module).'.php';
  13. $navigation = new Zend_Navigation($config);
  14. $view->navigation($navigation);
  15. }
  16. }
  17. }

Powyższą zawartość należy zapisać w pliku ModuleNavigation.php w folderze library\Plugins . Powyższy fragment odpowiada za odczytanie nazwy modułu (linijka 5) oraz pobraniu odpowiedniego pliku z menu z głównego katalogu modułu (linijka 12).

Jeszcze zostały 2 rzeczy do zrobienia. Musimy dodać do pliku konfiguracyjnego linijkę:

  1. autoloaderNamespaces.Plugin = "Plugins_"

Teraz w głównym pliku Bootstrap (w folderze application) dodamy klasę initPlugins() .

  1. protected function _initPlugins()
  2. {
  3. $this->bootstrap("frontController");
  4. $this->frontController->registerPlugin(new Plugins_ModuleNavigation);
  5. }

I gotowe :) Wszystko powinno działać.