Witam
Niedawno zacząłem bawić się ZF2. Niestety, jak dotąd, Zend\Form w połączeniu z Zend\Db sprawiają mi sporo problemów. Często w bardzo błahych sytuacjach.
Prosta relacja dwóch tabel:
miejsce:
+----+------+
| id | name |
+----+------+
zdarzenie:
+----+------+----------+
| id | name | place_id |
+----+------+----------+
Formularz przyjmuje obiekt klasy PlaceTable, żeby pobrać sobie z niego dane potrzebne do selecta. To rozwiązanie już mi się nie podoba, bo wcześniej muszę gdzieś stworzyć obiekt tej tabeli (np. w kontrolerze) a potem go wepchnąć do formularza.
class EventForm extends Form
{
protected $placeTable;
public function __construct(PlaceTable $placeTable)
{
$this->placeTable = $placeTable;
// ...
$this->add(array(
'name' => 'place',
'type' => 'Select',
'options' => array (
'label' => 'Place',
'empty_option' => '-- select place --',
'value_options' => $this->getPlacesForSelect()
),
));
// ...
}
protected function getPlacesForSelect()
{
$data = $this->placeTable->fetchAll();
$select = array();
foreach ($data as $place) {
$select[$place->getId()] = $place->getName();
}
return $select;
}
}
Po odebraniu danych z formularza muszę sprawdzić czy kategoria, którą wybrał użytkownik, istnieje w bazie danych (przecież mógł zmienić ID firebugiem). Wykorzystałem do tego celu validator InArray, który sprawdzi czy odebrane ID należą do zbioru, który mu podam. I tu jest problem. Jak przekazać do InputFilter tablicę z IDentyfikatorami miejsc? Wepchać obiekt PlaceTable w kontrolerze, tak jak do formularza?
Wyglądałoby to tak:
class Event implements InputFilterAwareInterface
{
protected $placeTable;
// ...
public function setPlaceTable(PlaceTable $pt)
{
$this->placeTable = $pt;
}
public function getPlaceTable()
{
return $this->placeTable;
}
public function getInputFilter()
{
if(!$this->inputFilter) {
$inputFilter = new InputFilter();
// ...
$inputFilter->add(array(
'name' => 'place',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'InArray',
'options' => array(
'haystack' => $this->getPlacesForSelect(),
),
),
),
));
// ...
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
protected function getPlacesForSelect()
{
return $this->getPlaceTable()->getIDs();
}
}
Znacie jakieś inne (bardziej eleganckie) rozwiązanie?
Pozdrawiam