Temat: Akcje kontrolera możliwe do wykonania tylko przez requestAction()

Witam koledzy, widzę że społeczność tego forum nie jest wielka, ale miło mi że mogłem do niej dołączyć. CakePHP to mój pierwszy framework, więc proszę o wyrozumiałość.

Ponieważ temat niewiele mówi o moim problemie, napisze o co mi chodzi.

Chcę zrobić dynamiczne menu na stronie pobierane z bazy danych. Pomyślałem że stworzę kontroller menu posiadający metodę getMenu() która nie renderuje strony tylko zwraca powiedzmy tablicę wartości przez return. Metoda ta miała by być wywoływana przez inne kntrolery metodą requestAction(), wyglądało by to powiedzmy tak:

class dowolnyController ext ...
{
  var $beforeFilter = array('firstGetMenu');

  function firstGetMenu()
  {
     set('menu', $this->requestAction('/menu/getMenu/'));
  }
  ...
}

Poza akcją getMenu w kontrolerze menu umieścił bym jeszcze logikę odpowiedzialną na edycję menu itd.
Problem teraz jest taki: jak sprawić żeby metoda getMenu osiągalna była jedynie przez requestAction z innych kontrolerów a nie osiągalna z poziomu przeglądarki : http://.../menu/getmenu, ponieważ nie wykonuje ona żadego widoku a jedynie zwraca wartości. W chwili obecnej po wywołaniu przez przeglądarkę /menu/getmenu dostaję ekran braku widoku dla metody. Oznaczenie metody getMenu() jako private też nic nie da ponieważ nie jest ona wtedy osiągalna przez requestAction().

Jeżeli koledzy znają rozwiązanie mojego problemu, ewentualne wiedzą że pobieranie menu na stronie powinno odbywać się inaczej niż ja to sobie wymyśliłem, proszę o pomoc i sugestie.

2

Odp: Akcje kontrolera możliwe do wykonania tylko przez requestAction()

Witaj vegetassj.
Po pierwsze, nie widzę przyczyny dla której miałbyś blokować dostęp do tej akcji spoza requestAction(). Możesz ją sobie nazwać w dowolny sposób, tak że nikt normalny nie odgadnie jej nazwy, ale tak naprawdę dalej nie widzę powodu aby to robić.

Jeżeli chodzi o pobieranie menu, requestAction - jak najbardziej, ale najlepiej by był on  wywoływany w elemencie. Dlaczego? Ponieważ można go łatwo cache'ować smile
Np. w layoucie tam gdzie chcesz wstawić menu : echo $this->element('nazwa_elementu', array('cache'=>'1 day'); , a w tym elemencie możesz mieć coś jak: echo $this->requestAction('/controllerJakis/akcja', array('return')); - nie pamiętam teraz kodu składni dokładnie, ale coś w tym stylu powinno działać (popatrz do API).
Pamiętaj, że każdorazowe wywołanie requestAction to tak jakbyś wywołał nowego cake'a. Biorąc pod uwagę, że menu jest praktycznie na każdej stronie dużo lepiej jest takie informacje cache'ować.

Pozdrawiam.

3 (edytowany przez mts 2008-07-23 00:11:59)

Odp: Akcje kontrolera możliwe do wykonania tylko przez requestAction()

Hej, odpowiedzialny jest za to parametr 'requested': uzywa się go w taki sposób w controllerze:

function index() {

if (isset($this->params['requested'])) { 

    // cos się dzieje gdy wywolany przez request action 

}
else { 

// tu normalnie przez adres  

}
}

Pozdro

4

Odp: Akcje kontrolera możliwe do wykonania tylko przez requestAction()

można jeszcze nazwać akcję zaczynająć od pokreślenia,np. _firstGetMenu(){ ... } wtedy akcja będzie niedośęgalna przez adres przeglądarki.., ale wewnątrz cake'a będzie ją można wykonywać

5

Odp: Akcje kontrolera możliwe do wykonania tylko przez requestAction()

witam,
wiem ze troche pozno dolaczam sie do watku, ale dopiero co sie zarejestrowalem, ( znaczy przypomnialem sobie login i haslo do forum smile ).
Jezeli chodzi o sprawe z menu nie uzywalbym requestAction - zbednie obciaza pamiec, "podwojnie" nabija statystyki i generalnie nie powinno sie jej uzywac.
Inne rozwiazanie : nie wiem czemu nie mozesz normalnie wywolac funckji z AppControllera , skoro i tak "dowolnyController" dziedziczy z AppController.
Wiec rozwiazanie wygladalo by mniej wiecej tak :

class AppController extends Controller {

function beforeFilter() {
  // w tym miejscu wyciagasz menu w postaci tabeli ( $menuTab ) z bazy danych, albo definiujesz funkcje, ktrora bedzie zwracala tablice z menu
  //.....
  //....

  // przekazanie zmiennej do layoutu  
$this->set( 'menuTab', $menuTab );
 
}
}
?>

po przekazaniu zmiennej $menuTab ( tablicy z menu ) renderujesz element, z parametrem $menuTab, w ktorym to elemencie odpowiednio obrabiasz tablice z menu np.

$this->element( 'menu', $menuTab );

i teraz tam gdzie chcesz miec menu poprostu renderujesz ten element z parametrem, ktory przechowuje tablice menu.

Wiem ze poznno pisany e-mail, ale od teraz bedzie ich czesciej smile