ZF2 - InputFilter dla pola typu select zawierającego dane z bazy (TableGateway).

0

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

0

A nie jest tak, że zend2 wywala błąd walidacji, jeśli w rezultacie otrzymał inną daną , niż zdefiniowałeś w OptionsValues?
Ja bym na twoim miejscu to sprawdził :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1