Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Zend] problem z Bootstrap
Forum PHP.pl > Forum > PHP > Frameworki
Fluke
Witam.

Mam mały problem z modułami w Zend oraz z Bootstraperem

Struktura katalogowa:
-application
--modules
---admin
----controllers
----views
----Bootstrap.php
---website
----controllers
----views
----Bootstrap.php
-Bootstrap.php

Plik .ini:
  1. [production]
  2. phpSettings.display_startup_errors = 1
  3. phpSettings.display_errors = 1
  4. includePaths.library = APPLICATION_PATH "/../library"
  5. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  6. bootstrap.class = "Bootstrap"
  7. appnamespace = "Application"
  8.  
  9. resources.modules[]=
  10. resources.frontController.defaultModule = "website"
  11. resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
  12. resources.frontController.params.displayExceptions = 0
  13. resources.layout.layoutPath = APPLICATION_PATH "/layout/scripts"
  14. resources.view[] =
  15.  
  16. admin.resources.layout.layoutPath = APPLICATION_PATH "/layout/scripts"
  17. admin.resources.view[] =
  18.  
  19. [staging : production]
  20.  
  21. [testing : production]
  22. phpSettings.display_startup_errors = 1
  23. phpSettings.display_errors = 1
  24.  
  25. [development : production]
  26. phpSettings.display_startup_errors = 1
  27. phpSettings.display_errors = 1
  28. resources.frontController.params.displayExceptions = 1



Głowny bootstrap.php:
  1. <?php
  2. Zend_Loader::loadClass("Zend_Application_Bootstrap_Bootstrap");
  3.  
  4. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  5. {
  6. protected function _initDoctype() {
  7. echo "Bootstrap of ROOT";
  8. }
  9.  
  10. }


Admin bootstrap.php
  1. <?php
  2. Zend_Loader::loadClass("Zend_Application_Bootstrap_Bootstrap");
  3.  
  4. class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
  5. {
  6. protected function _initDoctype() {
  7. echo "Bootstrap of ADMIN";
  8. $this->bootstrap("view");
  9. $view = $this->getResource("view");
  10. }
  11.  
  12. }


Website bootstrap.php
  1. <?php
  2. Zend_Loader::loadClass("Zend_Application_Bootstrap_Bootstrap");
  3.  
  4. class Website_Bootstrap extends Zend_Application_Module_Bootstrap
  5. {
  6. protected function _initDoctype() {
  7. echo "Bootstrap of WEBSITE";
  8. $this->bootstrap("view");
  9. $view = $this->getResource("view");
  10. $view->doctype('XHTML1_STRICT');
  11.  
  12. }
  13. }


Problem polega na tym, że wypisuje:
Bootstrap ROOT Bootstrap ADMIN oraz wyświetla zawartość modułu Website. Takie trochę pogmatwane coś to trochę i nie wiem co jest źle, idę na logikę czyli jak wcześniej w pliku .ini zadeklarowałem, że resource.frontController.defaultModule = "website" to czemu mi otwiera bootstrap`a admina...

Dodatkowo jak wpiszę:
localhost/admin -> uruchamia się ErrorController modułu website a nie admin.

Siedzę na tym cały dzień, przeszperałem wszystkie(chyba) strony anglojęzyczne z tym i ni ch..a

Z góry dziękuję za wszelką pomoc.

Pozdrawiam
pawv
W Zend Framework odpalane są Bootstrapy wszystkich modułów jakie zadeklarowane są w aplikacji.

W linku poniżej po angielsku opisane czemu
http://stackoverflow.com/questions/5304067...pecific-modules
Fluke
To nie rozumiem po co sa bootstrapy w modulach jak i tak zostana nadpisane.

Jak chcialem zmieniac w kazdym bootstrapie layout strony to ustawiany byl w tym ostatnim bootstrapie czyli u mnie w module website, bootstrap Website_Bootstrap.

Rozkminilem jak zmieniac layouty dla odpowiednich modolow za pomoca pluginow ale zastanawia mnie caly czas ta logika. Jeszcze nie probowalem ladowac pluginow w poszczegolnych modolach ale pewnie zostana zaladowane wszystkie ktore sa zdefiniowane w Bootstrap, Admin_Bootstrap, Website_Bootstrap.

Pozdrawiam.
ShadowD
No widzisz, Zend w v1 tak działa rozwiązaniem jest nie używanie jego lub dodanie jakiegoś pluginu, tak samo pliki konfiguracyjne, nie ma znaczenia jaki moduł jest aktywny i tak zostaną przeprasowane wszystkie wpisy nawet te zaczynające się od nazwy modułu. W drugiej wersji fw jest już to poprawione na wzór tego czego oczekujesz - z resztą na logikę tak powinno być od początku, ale Zend"owcy wymyślili to inaczej i powinniśmy się cieszyć z przyznania się do błędu i zmian. (beta można pobrać z głównej zf'a)

Ja osobiście mam takie rozwiązanie na podział modułowy i uzależnienie od tego lay'a. ;-)

Pliki są poukładane tak:
http://screenup.pl/?l=CEHQAY8

Całość odpowiada mi bardzo, a zmiany jakich trzeba dokonać są w miarę nie wielkie.

  1. [production]
  2. phpSettings.display_startup_errors = 0
  3. phpSettings.display_errors = 0
  4. includePaths.library = APPLICATION_PATH "/../library"
  5. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  6. bootstrap.class = "Bootstrap"
  7. appnamespace = "Application"
  8. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  9. resources.frontController.params.displayExceptions = 0
  10. autoloaderNamespaces[] = "Ss"
  11.  
  12. ;Położenie modułów
  13. resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
  14.  
  15. ;Widok
  16. resources.view[] = ""
  17.  
  18. ;Layout
  19. resources.layout.layout = default
  20. ;Default
  21. default.resources.layout.layoutPath = APPLICATION_PATH "/modules/default/layout/scripts"
  22. ;Admin
  23. admin.resources.layout.layoutPath = APPLICATION_PATH "/modules/admin/layout/scripts"


I boot:
  1. qw<?php
  2.  
  3. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  4. {
  5. protected function _initDoctype() {
  6. $this->bootstrap('view');
  7. $view = $this->getResource('view');
  8. $view->doctype('XHTML1_STRICT');
  9. }
  10.  
  11. protected function _initAutoload() {
  12. $qw=new Zend_Mail();
  13.  
  14. $autoloader = new Zend_Application_Module_Autoloader(array(
  15. 'namespace' => '',
  16. 'basePath' => dirname(__FILE__) . '/modules/default'
  17. ));
  18. $autoloader = new Zend_Application_Module_Autoloader(array(
  19. 'namespace' => 'Admin_',
  20. 'basePath' => dirname(__FILE__) . '/modules/admin'
  21. ));
  22. }
  23.  
  24. protected function _initLayoutHelper()
  25. {
  26. $this->bootstrap('frontController');
  27. $layout = Zend_Controller_Action_HelperBroker::addHelper(
  28. new Pro_Controller_Action_Helper_SetLayoutPath());
  29. }
  30. }
  31.  
  32. class Pro_Controller_Action_Helper_SetLayoutPath extends Zend_Controller_Action_Helper_Abstract
  33. {
  34. public function preDispatch()
  35. {
  36. $module = $this->getRequest()->getModuleName();
  37.  
  38. if ($bootstrap = $this->getActionController()
  39. ->getInvokeArg('bootstrap')) {
  40.  
  41. $config = $bootstrap->getOptions();
  42.  
  43. if (isset($config[$module]['resources']['layout']['layoutPath'])) {
  44. $layoutPath =
  45. $config[$module]['resources']['layout']['layoutPath'];
  46. $this->getActionController()
  47. ->getHelper('layout')
  48. ->setLayoutPath($layoutPath);
  49. }
  50. }
  51. }
  52. }


Kod metody "_initAutoload" jest uzależniony od ilości modułów, dla kolejnych musisz dodawać wpis (3 linie) - odpowiada za zmuszenie Zend'a do poszukiwania klas formów i modelów w odpowiednich modułach, aczkolwiek korzystanie z innych niż aktualnie edytowany jest możliwe, wszystko oparte jest na prefixach, dla modułów deklaracje podajemy ZAWSZE Z PREFIXEM danego modułu, a przy jego wywoływaniu jest trochę inaczej, moduł default nie wymaga prefixu, a każdy inny tak!

Całość ma podzielić aplikację na części, stronę główną firmy, bloga i panel który tym wszystkim zarządza - trochę inne podejście niż w założeniach mam wrażenie, ale dla mnie słuszne "moduł" to osobny system który może bez problemu działać bez innych części, a nie jakaś konkretna funkcjonalność np. news'y. ;-)

Mam nadzieję, że to Ci pomoże.
pawv
W podanym linku był przykład jak sensownie to rozwiązać. Tworzysz plugin ogólnie do layoutow. Nie ma sensu tworzyć pluginów dla każdego modułu oddzielnie. I w takim pluginie sprawdzasz jaki moduł jest załadowany i po niem ustawiasz layout.

  1. class Custom_Module_Plugin_DisableLoadLayout extends Zend_Controller_Plugin_Abstract {
  2. /*
  3.   * @param Zend_Controller_Request_Abstract $request
  4.   */
  5. public function preDispatch(Zend_Controller_Request_Abstract $request) {
  6. $module = $request->getModuleName();
  7. $layout = Zend_Layout::getMvcInstance();
  8.  
  9. switch($module){
  10. case "default":
  11. $layout->setLayout('layout');
  12. break;
  13. case "admin":
  14. $layout->setLayout('admin');
  15. break;
  16. }
  17. }
  18. }


ewentualnie

  1. class Custom_Module_Plugin_DisableLoadLayout extends Zend_Controller_Plugin_Abstract {
  2. /*
  3.   * @param Zend_Controller_Request_Abstract $request
  4.   */
  5. public function preDispatch(Zend_Controller_Request_Abstract $request) {
  6. $module = $request->getModuleName();
  7. $layout = Zend_Layout::getMvcInstance();
  8.  
  9. $layout->setLayoutPath('application/'.$module.'/layouts/scripts');
  10. }
  11. }


jeżeli wolisz tak jak poniżej napisał ShadowD trzymać layouty wewnatrz modułów
ShadowD
Z tego rozwiązanie taż korzystałem, zmuszało mnie do trzymania lay w jednym katalogu w obrębie całej aplikacji, w moim rozwiązaniu każdy moduł ma swój katalog w swoim ciele dzięki czemu każdy z modułów może mieć wiele lay'ów i wszystko nie jest zmiksowane. ;-)
Fluke
No właśnie, projektanci Zenda chyba tutaj tymi bootstrapami logiką nie zaszaleli...

Moim zdaniem najlepszym rozwiązaniem było by gdyby ładował się najpierw główny bootstrap a następnie odpowiedniego modułu. W ten sposób w głównym bootstrapie można byłby załadować plugina, który byłby odpowiedzialny za layout`y a resztę pluginów ładował by odpowiedni bootstrap w module.

Jeszcze natknąłem się na taki jeden problem odnośnie standardowego laya:
  1. resources.frontController.defaultModule = "admin"


Wyskakuje mi Zend_Application_Resource_Exception:
  1. with message 'Bootstrap file found for module "default" but bootstrap class "Default_Bootstrap" not found


Czyli może chodzi tutaj o to, że standardowy moduł ma się nazywać "Default". Jak robiłem moduły po przez:
  1. //...
  2. $Front = Zend_Controller_Front::getInstance();
  3. $Front->setDefaultModule("admin")l
  4. $Front->setDefaultModuleDirectory(APP."/modules");
  5. $Front->dispatch()

To w ten sposób wszystko chodziło jak należy.

Czyli pytanie: czy bootstrapy są potrzebne i tak każda aplikacja napisana w Zend powinna je mieć czy można sobie obrać jakąkolwiek drogę?
ShadowD
Ja z bootstrapa korzystam tylko głównego, co do Twojego pytania - lay nie musi być wybierany w bootstrapie, więc pisz tak jak jest Ci wygodniej. ;-)
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-2025 Invision Power Services, Inc.