Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony]Nowy walidator
Forum PHP.pl > Forum > PHP > Frameworki
kamil.deb
Witam

Chciałbym napisać nowy validator sprawdzający np. czy pierwsza litera wyrazu jest napisana wielką literą. Gdzie taką f. powinienem napisać.
destroyerr
Nie mogę znaleźć, a widziałem już coś przyzwoitego na ten temat.
Nic straconego, walidatory są proste. Jeśli to co w dokumentacji jest zawarte to za mało, to zajrzyj do wbudowanych walidatorów. Powinieneś dowiedzieć się tam wszystkiego.
W metodzie configure oczywiście konfigurujesz (ustawiasz dostępne opcje i wiadomości), a metoda doClean zajmuje się już walidacją. W przypadku błędu rzucasz wyjątkiem z klasy sfValidatorError lub sfValidatorErrorSchema. To chyba wszystko co najważniejsze.

Mam wrażenie, że na tym forum też już o tym było.
Crozin
O tym jak napisać walidator wspomniał już destroyerr, ja tylko dodam, że dobrze by było gdybyś odpowiednio przewidział miejsce zapisu nowego walidatora.
Jeżeli będzie on używany wyłącznie w obrębie jednego modułu to wrzucasz go do SF_ROOT/apps/APP/modules/MODULE/lib
Jeżeli w obrębie jednej aplikacji do SF_ROOT/apps/APP/lib
A jeżeli w obrębie całego projektu do SF_ROOT/lib

Pamiętaj tylko by nie mieszać Twoich plików ze źródłami Symfony
m-naw
Ja bym to zrobil tak:

  1. <?php
  2. class myValidatorFirstLetter extends sfValidatorSchema
  3. {
  4.  public function __construct($string, $options = array(), $messages = array())
  5.  {
  6.    $this->addOption('string', $string);
  7.    $this->addOption('throw_global_error', false);
  8.  
  9.    parent::__construct(null, $options, $messages);
  10.  }
  11.  
  12.  protected function doClean($values)
  13.  {
  14.    if (is_null($values))
  15.    {
  16.      $values = array();
  17.    }
  18.  
  19.    if (!is_array($values))
  20.    {
  21.      throw new InvalidArgumentException('Proszę podać parametr do metody doClean()');
  22.    }
  23.  
  24.    $string  = isset($values[$this->getOption('string')]) ? $values[$this->getOption('string')] : null;
  25.  
  26.    if(ucfirst($string) != $string)
  27.    {
  28.      throw new sfValidatorError($this, 'invalid');
  29.    }
  30.  
  31.    return $values;
  32.  }
  33. }
  34.  
  35. ?>


Widziałem niedawno ogłoszenie o prace gdzie jako zadanie trzeba było walidować imię aby pierwsza litera była z dużej. Czy czasem nie aplikujesz do nich? aaevil.gif
destroyerr
Dlaczego dziedziczysz po sfValidatorSchema. Wynikają z tego tylko dalsze błędy w kodzie. Zdecydowanie powinna być rozszerzana klasa sfValdiatorBase.

Cytat
  1. <?php
  2. public function __construct($string, $options = array(), $messages = array())
  3. {
  4.   $this->addOption('string', $string);
  5.   $this->addOption('throw_global_error', false);
  6.  
  7.   parent::__construct(null, $options, $messages);
  8. }
  9. ?>

Totalnie nie to miejsce, wspomniałem już wcześniej, że od tego jest metoda configure.
Opcja throw_global_error wcale nie jest obsłużona.

Cytat
  1. <?php
  2. if (is_null($values))
  3.   {
  4.     $values = array();
  5.   }
  6.  
  7.   if (!is_array($values))
  8.   {
  9.     throw new InvalidArgumentException('Proszę podać parametr do metody doClean()');
  10.   }
  11. ?>

A jeśli podam null w tym polu? to nadal nie będzie parametrów. Wywaliłbym ten wyjątek i skorzystał bym z opcji required.
-=Peter=-
A nie lepiej wykorzystać walidator symfony sfValidatorRegex z odpowiednim wyrażeniem regularnym?
destroyerr
Jeśli chodzi stricte o to sprawdzanie, to na pewno sfValidatorRegex jest lepszym rozwiązaniem, tym bardziej, że ten zaproponowany walidator nie sprawdza w ogóle czy to jest string.
Zastanawiałem się tylko jak wygląda sprawa wydajności z wyrażeniem regularnym. Jeśli to jest tylko jeden wyraz no to bez przesady, ale jeśli jest to tekst to lepiej wycinać pierwszą literę i dopiero sprawdzać, ale może też przesadzam.
m-naw
Przyznaje się, można to rozwiązać prościej. Co do błędów to moim zamierzeniem było użycie tego walidatora jako PostValidator (dlatego ValidatorSchema nie Base). Wcześniej pole byłoby sprawdzone sfValidatorString. No ale racja nie jest to dobre rozwiązanie.

  1. <?php
  2.  
  3. class myValidatorFirstLetter extends sfValidatorRegex
  4. {
  5.  
  6.  protected function configure($options = array(), $messages = array())
  7.  {
  8.    parent::configure($options, $messages);
  9.  
  10.    $this->setMessage('invalid', 'String musi składać się z liter i zaczynać się z dużej litery');
  11.    $this->setMessage('required', 'Proszę podać string');
  12.  
  13.    $this->setOption('pattern', '/^[A-Za-zĘÓĄŚŁŻŹŃęóąśłżźćń]+$/');
  14.  }
  15.  
  16.  protected function doClean($value)
  17.  {
  18.    $clean = parent::doClean($value);
  19.  
  20.    if(ucfirst($clean) != $clean)
  21.    {
  22.        throw new sfValidatorError($this, 'invalid');
  23.    }
  24.    
  25.    return $clean;
  26.  }
  27. }
  28. ?>


Jak widać to jest przypadek gdzie string miałby się składać z samych liter. A jaki wzorzec należałoby podać do sfValidatorRegex aby go użyć w tym przypadku?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.