teamon.eu

blah blah blah

[Symfony] Lepsze wykorzystanie error404

25 grudnia 2007

Kategorie:

Tagi:

  • PHP
  • Symfony
  • error404

W 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:

  1. Wyświetlić error pozostawiając layout (możliwość kliknięcia w menu i przejścia gdzie indziej)
  2. 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: true
 
Gotowe ;]

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

  • Michał Górny 25 grudnia 2007 19:35:12

    Jeszcze w cechach dobrej akcji 404 należałoby dołożyć, że nie powinna przekierowywać na inny adres.

  • teamon 25 grudnia 2007 19:36:20

    Nie przekierowuje. forward() tylko uruchamia inna akcje, redirect() przekierowuje pod inny adres :)

  • stach 06 maja 2008 15:21:00

    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?

  • stach 06 maja 2008 15:23:03

    aha, chyba o to ze ustawilem w ustawieniach domyslny modul default - wtedy chyba wymagana jest metoda executeError404 w kontrolerze default.
    zgadza sie?

Zostaw komentarz

code