[Symfony] Lepsze wykorzystanie error404
25 grudnia 2007W dokumentacji Symfony bardzo często jest coś w stylu
$this->forward404Unless($object);
Niby proste, niby fajne, niby wygodne.
Dlaczego tylko 'niby' ?
W praktyce forwarduje to do akcji default/error404 która objawia się tym, że jest bez layoutu i z nic nie mówiącym napisem 'Not found'
Osobiście chciałbym aby aplikacja była nieco bardziej przyjazna dla użytkownika
Dobra akcja 404 powinna:
- Wyświetlić error pozostawiając layout (możliwość kliknięcia w menu i przejścia gdzie indziej)
- Wyświetlić treść błędu w zależności od tego co się stało (np 'Product not found')
Nie pozostaje nic innego jak zabrać się do pracy :)
1. Pozostawienie layout
Otwieramy (tworzymy jeśli nie ma) plik MY_APP/modules/default/config/view.yml i wpisujemy w nim
error404Success: has_layout: trueGotowe ;]
2. Wyświetlenie własnej informacji
Ten krok jest nieco bardziej skomplikowany. Ktoś mogł zauważyć, że metoda forward404() ma jeszcze drugi opcjonalny parametr $message. Niestety jest on wykorzystywany tylko w logu. Aby w pełni wykorzystać jego potencjał musimy stworzyć własną klasę actions.
W MY_PROJECT/lib (najlepiej, może być też w MY_APP/lib) tworzymy plik customActions.class.php i wpisujemy w nim
<?php class customActions extends sfActions { }
Chcemy przekazać parametr $message do akcji error404 modułu default. Wykorzystamy do tego ficzer zwany flash
public function forward404($message = '') { $this->setFlash('error404Message', $message); throw new sfError404Exception($message); }
i do tego
public function forward404Unless($condition, $message = '') { if (!$condition) { $this->setFlash('error404Message', $message); throw new sfError404Exception($message); } } public function forward404If($condition, $message = '') { if ($condition) { $this->setFlash('error404Message', $message); throw new sfError404Exception($message); } }
Teraz pozostało nam jedynie wyświetlenie $message. W MY_APP/modules/default/templates/error404Success.php
<?php echo ($msg = $sf_flash->get('error404Message')) ? $msg : 'Error 404. Not found' ?>
Teraz we wszystkich modułach wystarczy zmienić klasę potomną pliku akcji MY_APP/MY_MODULE/actions/actions.class.php
class myModuleActions extends customActions
Możemy już wygodnie używać
$object = ObjectPeer::retrieveByPk($this->getRequestParameter('objectId')); $this->forward404Unless($object, 'Object not found');
Jak zawsze, wszelkie propozycje i uwagi mile widziane :)
4 komentarze
Jeszcze w cechach dobrej akcji 404 należałoby dołożyć, że nie powinna przekierowywać na inny adres.
Nie przekierowuje. forward() tylko uruchamia inna akcje, redirect() przekierowuje pod inny adres :)
mam taki blad:
Invalid configuration settings: [sf_error_404_module] "default", [sf_error_404_action] "error404"
ustawilem w app frontend tak jak napisales, w aplikacji backend nic nie ruszalem a mimo tego wlasnie taki blad mam.
wczesniej tego nie bylo - wywalal oryginalny 404 symfony.
ktos wie o co chodzi?
aha, chyba o to ze ustawilem w ustawieniach domyslny modul default - wtedy chyba wymagana jest metoda executeError404 w kontrolerze default.
zgadza sie?