Komponent formularzy frameworka symfony jest naprawdę bardzo potężnym narzędziem, pozwalającym na tworzenie zaawansowanych rozwiązań przetwarzających dane pochodzące od użytkownika na odpowiednią formę. O ile przetwarzanie formularza zazwyczaj sprowadza się do operacji na przesłanych do niego danych, o tyle czasem potrzebujemy innych, zawartych poza jego polami. W dzisiejszym wpisie chciałbym pokazać, w jaki sposób przekazać te dodatkowe dane do klasy naszego formularza. Zapraszam do lektury.

 

symfony: Przekazywanie dodatkowych danych do klasy formularza.

Weźmy pod uwagę następującą sytuację: mamy moduł głosowania, w którym każdy użytkownik identyfikowany przez adres IP może zagłosować tylko raz dziennie. Każdy głos wymaga też wypełnienia kilku innych pól, które jednak mogą mieć dowolne dane.

Wszystkie pola formularza zostaną przekazane do niego po wysłaniu poprzez metodę bind(), aczkolwiek musimy też sprawdzić, czy dany adres IP “nie głosował już” w ciągu ostatniego dnia. Sam mechanizm sprawdzający pominiemy, zresztą pisałem o podobnym problemie ostatnio we wpisie o przedziałach czasu w zapytaniach SQL. Musimy zatem znaleźć sposób na przekazanie danych o adresie IP użytkownika do formularza.

Próbując rozwiązać ten problem nie znalazłem żadnego sposobu pozwalającego na “podpięcie” dodatkowych danych do formularza. Jedynym rozwiązaniem zdaje się być przekazanie ich do wnętrza podczas tworzenia samego obiektu. Jak to zrobić?

Jeśli weźmiemy pod uwagę deklarację konstruktora klasy sfForm:

public function __construct($defaults = array(), $options = array(), $CSRFSecret = null)
	{
	// ...
	}

zauważymy, że przyjmuje on jako drugi parametr tablicę $options. Okazuje się, że właśnie ona jest kontenerem dodatkowych parametrów przekazywanych do klasy formularza. Jeśli zatem stworzymy klasę o nazwie np. CustomForm, to możemy stworzyć jej obiekt w następujący sposób:

class CustomForm extends sfForm
	{
	// ...
	}

$customForm = new CustomForm(array(), array('ip' => $_SERVER['REMOTE_ADDR']));

W tym momencie, aby uzyskać dostęp do klucza “ip”, musimy jedynie wewnątrz, np. w metodzie validate(), skorzystać z następującej instrukcji:

$ipAddress = $this->getOption('ip');

…i to wszystko. Teraz możemy używać przekazanych danych zgodnie z naszymi wymaganiami.

Jeśli macie inne pomysły / sposoby na osiągnięcie postawionego w tym wpisie celu, zapraszam do komentowania.