Framework symfony, jak praktycznie każdy na rynku ma swoje “smaczki”, które czasem umilają, a czasem bardzo utrudniają tworzenie kolejnych funkcji projektu - zamiast zająć się właściwą pracą musimy przeszukiwać strony manuala i “czeluści” Internetu, aby znaleźć Jedyną Słuszną ™ drogę wykonania danego zadania. W dzisiejszym wpisie chciałbym pokazać, w jaki sposób “dobrać się” do “niewyescape’owanych” danych [konia z rzędem temu, kto poda dobre polskie tłumaczenie tego terminu ;]] tablicy zamkniętej w kontenerze klasy sfOutputEscaperArrayDecorator.

Fotografia: Dominic Alves, CC-BY.

symfony: Pobieranie tablic z obiektów klasy sfOutputEscaperArrayDecorator.

Problem jest krótki i prosty - w przypadku danych wszystkich typów poza arrayem w widokach symfony otrzymujemy te same dane, które podpięliśmy w kontrolerze. Pech chciał, że twórcy frameworka uznali, że kontener klasy o przydługiej nazwie będzie lepszym sposobem na zaprezentowanie go w widoku, stąd też ktoś, kto chciałby skorzystać ze zwykłej tablicy ma nieco utrudnione zadanie.

Wszystkiemu “winne” jest “escape’owanie” treści przesyłanych do widoku, które chroni m. in. przed atakami XSS. Czasem jednak te tablice zawierają dane, które celowo mają zostać przesłane do widoku w “czystej” formie. Co należy wtedy zrobić?

Rozwiązania są dwa - można albo wyłączyć escape’owanie danych [nie polecam] lub po prostu pobrać czyste dane z kontenera. Aby wyłączyć escape’owanie należy zmienić jedynie ustawienie escaping_strategy w pliku settings.yml naszej aplikacji:

# apps/frontend/config/settings.yml

all:
  escaping_strategy:    false

Nie jest to jednak dobry pomysł, ponieważ na dłuższą metę chcielibyśmy raczej, żeby to framework pracował za nas i automatycznie przetwarzał dane, z których zdecydowana większość na pewno powinna być escape’owana. Dlatego lepszym rozwiązaniem będzie skorzystanie z metody getRaw() zmiennej $sf_data będącej ogólnym kontenerem danych przekazywanych do widoku. Zakładając, że podpięliśmy tablicę danych w zmiennej $data do indeksu records w kontrolerze:

$this->records = $data;

Pobierzemy ją z powrotem w następujący sposób:

$cleanRecords = $sf_data->getRaw('records');

Zmienna $cleanRecords zawiera dokładnie te same dane, co wcześniej tablica $data w kontrolerze. W ten sposób możemy do woli wyświetlać różnego rodzaju dane typu kod HTML, skrypty JavaScript, itp.

Być może znacie lepsze rozwiązanie tego problemu - dajcie znać w komentarzach. Z góry dziękuję za wszelkie opinie na ten temat. ;]