Prowadzenie blogu ma, a przynajmniej powinno mieć na celu niesienie pomocy Czytelnikom. Czasem jednak trzeba też pomóc sobie - autorowi. Najlepiej jest wtedy, kiedy przy okazji spełniania tego pierwszego wymagania, spełnia się przy okazji to drugie. Ze względu na to, że tworzenie wpisów pomaga mi w uporządkowaniu wielu informacji kołaczących się nieskładnie w głowie, czasem będę się dzielił z Wami krótkimi wpisami o problemach, których rozwiązań często zapominam. Jednym z takich problemów jest właśnie tytułowe generowanie adresu URL w symfony, pochodzącego z routingu projektu… w kontrolerze.

Fotografia: Andreia, CC-BY.

symfony: Generowanie adresu URL route’a w kontrolerze modułu.

Kiedy szukałem rozwiązania tego problemu po raz pierwszy, podobnie jak we wtorkowym wpisie o pobieraniu flashów, niestety nie udało mi się trafić na gotowy “jednolinijkowiec” - kawałek kodu, który by wszystko bezproblemowo obsłużył. Stąd też pomysł na podzielenie się tym, co udało mi się uzyskać.

W czym problem, zapytacie? Otóż, jeśli mieliście okazję kiedyś realizować jakikolwiek projekt z użyciem frameworka symfony w wersji 1.x, na pewno trafiliście na funkcję - helper url_for(). Przyjmuje ona za parametr string zawierający nazwę żądanej “ścieżki” - route’a oraz jej parametry zapisane w formie query stringa. Biorąc pod uwagę w miarę prosty przykład:

showPage:
  url:  /page/:id
  param:
    module: page
    action: show  requirements:
    id: \d+

Następujący kod:

echo url_for('@showPage?id=5');

Wygeneruje nam odpowiedni link:

/page/5
Prawda, że proste? To wszystko jednak dzieje się w widoku, a więc w miejscu, w którym generowanie linków jest w pewnym sensie “naturalne”. Co jednak, jeśli potrzebowalibyśmy wygenerować taki link w kontrolerze?

W tym momencie oczywiście otwiera się dyskusja na temat sensowności takiej operacji. Na potrzeby artykułu załóżmy, że tworzymy funkcjonalność rejestracji konta użytkownika. Po zapisaniu danych formularza do bazy danych chcielibyśmy wysłać mu maila z linkiem zawierającym kod aktywacyjny dla jego profilu. Nie chcemy renderować całego szablonu emaila - wystarczy nam kawałek tekstu zapisanego np. w formie HEREDOCa:

$mailContents = <<<EOF
Witaj!

Aktywuj konto klikając w link:
{$activateUrl}

Pozdrawiamy.
EOF;

Załóżmy też, że dla ułatwienia sobie życia zdefiniowaliśmy route’a:

activateAccount:
  url: /user/activate/:code
  param:
    module: user
    action: activate

do którego wystarczy podać kod aktywacyjny celem otrzymania gotowego odnośnika aktywacyjnego. Proste? Teoretycznie.

Na jednym z forów internetowych znalazłem odpowiedź na moje pytanie. Bynajmniej nie było ono intuicyjne, czyli nie należało do kategorii “doświadczenie” - zdecydowanie była to “wiedza”. ;] Aby dostać się do funkcjonalności generowania URLa w kontrolerze, należy użyć następującego fragmentu kodu:

$activateUrl = $this->getController()->genUrl('@activateAccount?code='.$user->activationCode, true);

Parametr true oznacza, że link ma być “bezwzględny”, a więc http:// z domeną, katalogami, itd.

Mam nadzieję, że będę teraz pamiętał ten “skrawek”, a w razie czego będę mógł wrócić do tego wpisu i przypomnieć sobie, “jak to wszystko leciało”. ;]