ZF: Długości pól formularza na podstawie bazy

Kiedy tworzymy formularz w Zend Frameworku przesyłamy potem dane z niego do bazy. Czasem się okazuje, że długość wprowadzanych danych przekracza długość pola tabeli i przez to pojawia się błąd w stylu „String data, right truncated: 7 ERROR value too long for type character varying(40)” (PostgreSQL). Żeby temu zapobiec można ustawić dodatkowe walidatory dla pól formularza, które będą bazowały na informacjach z metadanych tabeli. Można to osiągnąć m.in. tak:

public function ustawWalidatory($aMetadane, $bInfoLabel = true)
{
    $elementy = $this->getElements();
        foreach($elementy as $sNazwa => $element) {
            $sNazwa = narzedziownia::fromCamelCase($sNazwa);
            if(!empty($aMetadane[$sNazwa]['LENGTH']) 
			&& !$element instanceof Zend_Form_Element_Hidden 
			&& !$element instanceof Zend_Form_Element_Checkbox
			&& $aMetadane[$sNazwa]['DATA_TYPE'] != 'date') {
                $nLength = $aMetadane[$sNazwa]['LENGTH'];
                $element->addValidator('StringLength', false, array(
                    'min'       => 1,
                    'max'       => $nLength,
                    'messages'  => array(
                        'stringLengthInvalid'   => 'Nie przesłano stringa, tylko coś innego',
                        'stringLengthTooShort'  => 'Za krótki ciąg znaków, wymagane co najmniej %min%',
                        'stringLengthTooLong'   => 'Za długi ciąg znaków, wymagane najwyżej %max%'
                    )
                ));

                // doklej informację do 'labela'
                if($bInfoLabel) {
                    $element->setLabel($element->getLabel() . ' [' . $nLength . ']');
                }
            }
        }
}

Po kolei. Funkcję dodajemy do formularza

// application/forms/NaszForm.php
public NaszForm extends Zend_Form
{
    public function init()
    {
        // tutaj inicjalizacja formularza
    }

    public function ustawWalidatory($aMetadata)
    {
        // tutaj treść funkcji jak wyżej
    }
}

Żeby pobrać metadane wystarczy wywołać metodę info() dla naszego modelu rozszerzającego Zend_Db_Table_Abstract (patrz: Zend_Db_Table_Abstract->info()).
Przelatujemy po wszystkich elementach dodanych do formularza. Sprawdzamy, czy dane pole przypadkiem nie jest checkboxem lub polem ukrytym (hidden) i czy ma w ogóle ustawioną długość (np. pole typu varchar bez podanej długości lub typu text – nie ma). Jeśli tak – ustaw walidator długości znaków od 1 do długości pola tabeli. Jeśli pole nie jest wymagane, to można ustawić długość od zera (min => 0). Na koniec ustawienie komunikatów walidatora i doklejenie informacji o długości pola do elementu Label.

Dobra, jeszcze jak to wywołać. Tu jest minus, bo nie zrobimy tego przekazując parametr do metody Zend_Form::init() – bo nie przyjmuje ona parametrów. Można wywołać funkcję niezależnie, np:

$form = new NaszForm();
// $tabela jest typu rozszerzającego Zend_Db_Table_Abstract
$aMetadane = $tabela->info('metadata');
$form->ustawWalidatory($aMetadane);

lub wykorzystać fakt, że przy tworzeniu obiektu klasy Zend_Form (lub dziedziczącej) w konstruktorze wywoływana jest metoda setOptions(), która może wywołać dowolną zdefiniowaną przez nas metodę, która zaczyna się od set. Czyli coś w tym stylu:

// $tabela jest typu rozszerzającego Zend_Db_Table_Abstract
$aMetadane = $tabela->info('metadata');

$form = new NaszForm(array(
    'walidatory'    => array(
        'metadane'  => $aMetadane
    )
));

Wówczas NaszForm musi posiadać metodę setWalidatory($aWalidatory), która ustawi walidatory. Mnie wygodnie było to zrobić tak:

public function setWalidatory(array $aWalidatory)
    {
        $aMetadane = $aWalidatory['metadane'];
        $bInfoLabel = strlen($aWalidatory['infolabel']) > 0 ? $aWalidatory['infolabel'] : true;

        $this->ustawWalidatory($aMetadane, $bInfoLabel);
    }

Można też bezpośrednio zmienić nazwę metody ustawWalidatory() na setWalidatory() i odpowiednio ustawić parametry.
I powinno działać.

Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Zdjęcie na Google+

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s