Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [symfony] sfValidatorPropelUnique z sfValidatorPropelChoiceMany
Forum PHP.pl > Forum > PHP > Frameworki
thomas2411
Witam

Mam tablicę z indeksem unikalności na 3 kolumnach i używam poniższego walidatora dodatkowo:
  1. $this->validatorSchema->setPostValidator(
  2. new sfValidatorPropelUnique(array('model' => 'ProduktPartner',
  3. 'column' => array('partner', 'product', 'language')))
  4. );


Działa jak trzeba, ale chciałbym to zrobić nieco inaczej. Chciałbym mieć formularz gdzie wybieram partnera, produkt i kilka języków dla nich. Następnie zapisuje (co już mam zrobione) to jako oddzielne obiekty. Dla każdego języka ten sam produkt i partner. Niestety tutaj validator nie działa. Wiem, dlaczego, ale nie wiem jak to rozwiązać. Jakieś propozycje?
Berg
Do głowy przychodzi mi tylko zbudowanie własnej metody sprawdzającej wartości pól i podpięcie jej pod formularz:
  1.  
  2. public function configure() {
  3. $this->validatorSchema->setPostValidator(new sfValidatorCallback(array( 'callback' => array($this, 'sprawdzUnikalnosc'))));
  4. }
  5.  
  6. public function sprawdzUnikalnosc($validator, $values, $aArguments) {
  7. // Odczyt przesłanych wartości
  8. $partner = $values['partner'];
  9. $product = $values['product'];
  10. $language = $values['language'];
  11.  
  12. // Tutaj kod odpowiedzialny za sprawdzanie unikalności w bazie danych
  13.  
  14. if(!$status) { // Jeśli rekordy są już w bazie danych to skrypt rzuca wyjątkiem
  15. $error = new sfValidatorError($validator, 'Jakiś komunikat z błędem...');
  16. throw new sfValidatorErrorSchema($validator, array('' => $error));
  17. }
  18.  
  19. return $values; // Jeśli wyjątek nie został rzucony to skrypt zwraca tablicę z przesłanymi wartościami
  20. }

Oczywiście w przypadku własnego walidatora należy wywalić sfValidatorPropelUnique smile.gif
Jeśli chodzi o sfValidatorErrorSchema to w tablicy pierwszy parametr może być albo nazwą pola (np. 'partner') lub też może być pustym stringiem. Jeśli będzie pusty to error zostanie potraktowany jako globalny i wyświetlony na górze formularza, jeśli natomiast będzie to nazwa pola to error zostanie wyświetlony przy określonym polu.
thomas2411
Na ile jest to "czyste rozwiązanie" nie wiem, ale działa wyśmienicie smile.gif dziękuje. Z tej formy używania funkcji już korzystałem mając problem ze sprawdzaniem unikalności PrimaryKey, który jest VARCHAR, a nie INT. Metoda praktycznie taka sama. Aż dziw bierze, że na to nie wpadłem. Pewnie można by to ubrać w jakiś ładny Validator, ale na chwilę obecną nie ma na to czasu. Zrobiłem więc tą funkcję lekko sparametryzowana. Nie wiem na ile wydajnie, ale działa smile.gif

Raz jeszcze dziękuję i pozdrawiam.


  1.  
  2. public function configure()
  3. {
  4. // (...)
  5. $this->validatorSchema->setPostValidator(
  6. new sfValidatorCallback(array(
  7. 'callback' => array($this, 'checkUniqueness'),
  8. 'arguments' => array(
  9. 'model' => 'ProduktPartner',
  10. 'multiple_column' => 'jezyki_logo',
  11. 'columns' => array('partner_logo', 'seria_logo', 'jezyki_logo')
  12. ))));
  13. }
  14.  
  15. public function checkUniqueness($validator, $values, $aArguments)
  16. {
  17. //Dla każdej wartości z kolumny multiple_column, która może mieć wiele wartości sprawdza istnienie obiektu
  18. foreach ($values[$aArguments['multiple_column']] as $one_of_many)
  19. {
  20. $criteria = new Criteria();
  21. //Generuje kryteria oddzielnie dla każdej wartości multiple_column
  22. foreach ($aArguments['columns'] as $column)
  23. {
  24. $colName = call_user_func(array(constant($aArguments['model'].'::PEER'), 'translateFieldName'), $column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
  25. if($column != $aArguments['multiple_column'])
  26. $criteria->add($colName, $values[$column]);
  27. else
  28. $criteria->add($colName, $one_of_many);
  29. }
  30. //Sprawdza w bazie istnienie takiego obiektu
  31. $object = call_user_func(array(constant($aArguments['model'].'::PEER'), 'doSelectOne'), $criteria);
  32.  
  33. //Jeśli istnieje wyrzuca wyjątek
  34. if(is_object($object))
  35. {
  36. $error = new sfValidatorError($validator, sprintf('An object with the same %s "%s" already exist.', $aArguments['multiple_column'], $one_of_many));
  37. throw new sfValidatorErrorSchema($validator, array('' => $error));
  38. }
  39. }
  40. return $values; // Jeśli wyjątek nie został rzucony to skrypt zwraca tablicę z przesłanymi wartościami
  41. }


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.