Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony]setError
Forum PHP.pl > Forum > PHP > Frameworki
Lonas
Jak mogę w symfony 1.2 ustawić setError ?

Jak mogę zrobić walidacje wysokosci i szerokosci obrazka ? dopisac do sfFileValidator kod odpowiedzialny za to czy w jakis inny sposób ?
AxZx
  1. <?php
  2. $this->setValidators(array(
  3.            'tytul'    =>    new sfValidatorString(
  4.                array('min_length'=>3, 'max_length' => 140, 'required' => true),
  5.                array('min_length'=>'za krótki tytuł', 'max_length'=>'za długi tytuł', 'required'=>'brak tytułu')
  6.            )
  7.        ));
  8. ?>


walidacje obrazka musisz zrobić samemu.
wydaje mi się, że można to zrobić tak:
tworzysz swoją klasę walidacji np. myValidatorFile
tam nadpisujesz metodę doclean.
w niej wykonujesz nadrzędną metodę doclean, sprawdzasz zapisany plik i jego rozmiary, jeżeli są za duże czy nie dozwolone to zwracasz wyjątek
throw new sfValidatorError
Lonas
Znalazlem gotowa klase ale nie dla symfony 1.2 moze to przerobie

http://snippets.symfony-project.org/snippet/259
AxZx
właśnie, tak jak napisałem;)
  1. <?php
  2. class sfFileImageValidator extends sfFileValidator
  3. {
  4.  function doClean($value){
  5.    if(parent::doClean($value)){
  6. ...
  7.    }
  8.  }
  9. }
  10. ?>


trzeba się przyjrzeć jak to wszystko jest zrobione i później już fajnie się z tego korzysta.
Lonas
Nie wiem czemu jak próbuje tego użyc to wywala błąd :
sfFileImageValidator does not support the following options: 'max_width'.


  1. <?php
  2. 'file_path'  => new sfFileImageValidator(array('path' => sfConfig::get('sf_upload_dir').'/gallery/temp','required' => true,'mime_types' => array('image/jpeg','image/pjpeg'),'max_size' => '261120','max_width' =>'200'), array('mime_types' =>'Nieprawidłowy format pliku','max_size'=>'Za duży rozmiar pliku. Limit to 255 Kb','required'=>'Wybierz zdjęcie')  )
  3. ?>
destroyerr
To dlatego, że walidator podczas konfigurowania nie dodaje (rejestruje) takiej opcji. Musisz w metodzie sfFileImageValidator::configure(), dodać te opcje:
  1. <?php
  2. class sfFileImageValidator extends sfValidatorFile
  3. {
  4.  protected function configure($options = array(), $messages = array())
  5.  {
  6.    $this->addOption('mime_types');
  7.    //a jesli chcesz dodac opcje wymagana, to:
  8.    $this->addRequiredOption('mime_types');
  9.  }
  10. }
  11. ?>


Tak samo jest z wiadomościami.
Lonas
Faktycznie dzięki - zrobiłem jak piszesz tyle że walidator nie działa - nie wyświetla komunikatu o błędzie

opcje dodałem do klasy sfValidatorFile
destroyerr
Po części mój błąd, bo domyślam się, że tego nie zrobiłeś: parent::configure($options, $messages). Jeśli nadal nie działa jak powinno, to bez kodu nic nie zrobimy.
Po drugie, nie wiem czemu akurat dodałeś opcje do sfValidatorFile.
Lonas
Zrobiłem ale też nie działo :/ walidator wygląda tak :

  1. <?php
  2. class sfFileImageValidator extends sfValidatorFile
  3. {
  4.  /**
  5.    * Executes this validator.
  6.    *
  7.    * @param mixed A file or parameter value/array
  8.    * @param error An error message reference
  9.    *
  10.    * @return bool true, if this validator executes successfully, otherwise false
  11.    */
  12.  protected function configure($options = array(), $messages = array())
  13.  {
  14.    parent::configure($options, $messages);
  15.  
  16.    $this->addOption('max_width');
  17.    $this->addMessage('max_width', 'tttt');
  18.  }
  19.  
  20.  
  21.  public function execute(&$value, &$error)
  22.  {
  23.    if (parent::execute($value, $error))
  24.    {
  25.      list($width, $height) = @getimagesize($value['tmp_name']);
  26.  
  27.      // File is not a square
  28.      $is_square = $this->getParameter('is_square');
  29.      if ($is_square && $width != $height)
  30.      {
  31.        $error = $this->getParameter('is_square_error');
  32.  
  33.        return false;
  34.      }
  35.  
  36.      // File height too large
  37.      $max_height = $this->getParameter('max_height');
  38.      if ($max_height !== null && $max_height < $height)
  39.      {
  40.        $error = $this->getParameter('max_height_error');
  41.  
  42.        return false;
  43.      }
  44.  
  45.      // File width too large
  46.      $max_width = $this->getParameter('max_width');
  47.      if ($max_width !== null && $max_width < $width)
  48.      {
  49.        $error = $this->getParameter('max_width_error');
  50.  
  51.        return false;
  52.      }
  53.  
  54.      // File height too small
  55.      $min_height = $this->getParameter('min_height');
  56.      if ($min_height !== null && $min_height > $height)
  57.      {
  58.        $error = $this->getParameter('min_height_error');
  59.  
  60.        return false;
  61.      }
  62.  
  63.      // File width too small
  64.      $min_width = $this->getParameter('min_width');
  65.      if ($min_width !== null && $min_width > $width)
  66.      {
  67.        $error = $this->getParameter('min_width_error');
  68.  
  69.        return false;
  70.      }
  71.  
  72.      return true;
  73.    }
  74.  }
  75.  
  76.  /**
  77.    * Initializes this validator.
  78.    *
  79.    * @param sfContext The current application context
  80.    * @param array   An associative array of initialization parameters
  81.    *
  82.    * @return bool true, if initialization completes successfully, otherwise false
  83.    */
  84.  public function initialize($context, $parameters = null)
  85.  {
  86.    // initialize parent
  87.    parent::initialize($context, $parameters);
  88.  
  89.    // set defaults
  90.    $this->getParameterHolder()->set('max_height',        null);
  91.    $this->getParameterHolder()->set('max_height_error',  'The file height is too large');
  92.    $this->getParameterHolder()->set('max_width',         null);
  93.    $this->getParameterHolder()->set('max_width_error',   'The file width is too large');
  94.    $this->getParameterHolder()->set('min_height',        null);
  95.    $this->getParameterHolder()->set('min_height_error',  'The file height is too small');
  96.    $this->getParameterHolder()->set('min_width',         null);
  97.    $this->getParameterHolder()->set('min_width_error',   'The file width is too small');
  98.    $this->getParameterHolder()->set('is_square',         false);
  99.    $this->getParameterHolder()->set('is_square_error',   'The file is not a square');
  100.  
  101.    $this->getParameterHolder()->add($parameters);
  102.  
  103.    return true;
  104.  }
  105. }
  106. ?>


walidacja

  1. <?php
  2. $this->setValidators(array(
  3.        'photo_id'    => new sfValidatorPropelChoice(array('model' => 'Photo', 'column' => 'photo_id', 'required' => false)),
  4.        'gallery_id'  => new sfValidatorChoice(array('choices' => array_keys(Gallery::getValuesToSelectGallery1()))),
  5.        'title'       => new sfValidatorString(array('min_length' => 1), array('required' => 'Wpisz tytuł zdjęcia')),
  6.        'file_patch'  => new sfFileImageValidator(array('path' => sfConfig::get('sf_upload_dir').'/gallery/temp','required' => true,'mime_types' => array('image/jpeg','image/pjpeg'),'max_size' => '261120','max_width' =>'200'), array('mime_types' =>'Nieprawidłowy format pliku','max_size'=>'Za duży rozmiar pliku. Limit to 255 Kb','required'=>'Wybierz zdjęcie')  ),
  7.        'description' => new sfValidatorString(array('required' => false)),
  8.        'tags'        => new sfValidatorString(array('required' => false)),
  9.      ));
  10. ?>


Wrzucajac zdjecie na serwer w ogole nie ma walidacji szerokosci tego pliku
mike
Jako, że tytuł wątku i pośrednio tematyka bardzo mi pasuje to się podłączę. Jak przekazać do formularza dodatkowe błędy?

Sytuacja jest następująca. Mam formularz rozszerzający sfFormPropel. Po wykonaniu validacji formularza chciałbym wykonać trochę logiki w kontrolerze, w którym jest on zawarty.
Robię sobie zwykłe $form->save(). Jeśli zapis wywoła wyjątek to sfFormPropel::save() propaguje ten wyjątek. A ja chciałbym jego treść przekazać jako jeden z błędów formularza.
  1. <?php
  2.  
  3. // Utworzenie formularza i...
  4. $this->adminForm = new AdminForm();
  5. // ...przekazanie go do widoku.
  6. $this->setVar('adminForm', $this->adminForm);
  7.  
  8. // Jeśli żądania jest typu POST i przetwarzanie formularza powiodło się...
  9. if ($request->getMethod() === sfRequest::POST
  10.    && $this->processForm($request, $this->adminForm)) {
  11.  
  12.    // ...to dokonywana jest próba zapisu
  13.    try {
  14.        $this->adminForm->save();
  15.  
  16.        /* @var $admin Admin */
  17.        $admin = $this->adminForm->getObject();
  18.  
  19.        // Ustawienie komunikatu
  20.        $this->getUser()->setFlash('create', "Utworzono nowego administratora ($admin)");
  21.        // Przekierowanie na widok główny modułu zarządzania administratorami
  22.        $this->redirect('@admins');
  23.    } catch (Exception $e) {
  24.        // Logowanie błędu
  25.        sfContext::getInstance()->getLogger()->err($e->getMessage());
  26.        // Ustawienie komunikatu o niepowodzeniu
  27.        $this->errors = array('Nie udało się utworzyć nowego administratora');
  28.    }
  29. }
  30.  
  31. ?>

W 28 linii jestem zmuszony przekazywać błąd do widoku poza formularzem. Wiem, że w zasadzie błędy formularza to logicznie co innego niż błędy wynikające z logiki biznesowej ale chciałbym użyć mechanizmów formularza żeby te błędy wyświetlić. Ot taka neichęc do dublowania kodu.
Lonas
No własnie w symfony 1.0, 1.1 było prosto setError i chyba tyle :/
mike
Cytat(Lonas @ 23.03.2009, 11:46:04 ) *
No własnie w symfony 1.0, 1.1 było prosto setError i chyba tyle :/
Wyrzucenie błędów z sfRequest to akurat dobra decyzja. Było to wygodne ale jakoś mnie to kuło w oczy.
Pozostała jednak luka bo błędy związane z formularzami zostały załatwione. Na błędy związane z logiką nie ma pomysłu.
destroyerr
@Lonas, walidator nie działa z prostej przyczyny. Metoda execute nigdy nie zostanie wykonana. Zajrzyj do książki o formularzach, powinno coś byc.

@mike, co do Twojego problemu to jest to dłuższa historia. Nie wiem jak wygląda u Ciebie metoda processForm, domyślam się, że standardowo tylko wtedy powstaje problem. Ty masz wynik tej metody w warunku i po prostu nie wiem. Wiec zakładam, że jest to metoda wygenerowana:
  1. <?php
  2. // Utworzenie formularza i...
  3. $this->adminForm = new AdminForm();
  4. // ...przekazanie go do widoku.
  5. $this->setVar('adminForm', $this->adminForm);
  6.  
  7. // Jeśli żądania jest typu POST
  8. if ($request->getMethod() === sfRequest::POST)
  9. {
  10.  
  11.   // ...to dokonywana jest próba zapisu
  12.    try
  13.    {
  14.        $this->processForm($request, $this->adminForm);
  15.  
  16.        /* @var $admin Admin */
  17.        $admin = $this->adminForm->getObject();
  18.  
  19.        // Ustawienie komunikatu
  20.        $this->getUser()->setFlash('create', "Utworzono nowego administratora ($admin)");
  21.        // Przekierowanie na widok główny modułu zarządzania administratorami
  22.        $this->redirect('@admins');
  23.    }
  24.    catch (Exception $e)
  25.    {
  26.        // Logowanie błędu
  27.        sfContext::getInstance()->getLogger()->err($e->getMessage());
  28.        // Ustawienie komunikatu o niepowodzeniu
  29.        $this->adminForm->getErrorSchema()->addError(
  30.            new sfValidatorError(new sfValidatorInteger(), 'min', array('value' => 15, 'min' => 18))
  31.        );
  32.   }
  33. }
  34. ?>

Szkorzystałem z sfValidatorInteger, ponieważ nie wiem jaki błąd masz, pewnie jakiś od bazy ale to już sobie sam rozwiążesz. Najlepiej chyba będzie nadpisać klase sfValidatorError i to tak, żeby w konstruktorze nie trzeba było podawać obiektu walidatora.
mike
Cytat(destroyerr @ 23.03.2009, 13:05:14 ) *
@mike, co do Twojego problemu to jest to dłuższa historia. Nie wiem jak wygląda u Ciebie metoda processForm (...)
Bindowanie parametrów żądania z polami formularza i wykonanie isValid(), które to jest zwracane jako rezultat działania funkcji.
Cytat(destroyerr @ 23.03.2009, 13:05:14 ) *
(...) nie wiem jaki błąd masz, pewnie jakiś od bazy ale to już sobie sam rozwiążesz. Najlepiej chyba będzie nadpisać klase sfValidatorError i to tak, żeby w konstruktorze nie trzeba było podawać obiektu walidatora.
1. Błęd to powiedzmy: baza strzeliła focha :-)
2. No właśnie te validatory w konstruktorze całkowici mi są nie na rękę :-) Faktycznie napisanie swojej klasy błędów będzie niezłym pomysłem a do konstruktora będę pchał neutralnego sfValidatorPass z komunikatem invalid.

Dzięki ~destroyerr. Kliknąłbym Ci pomógł ale i nie mój wątek, i uprawnień moda się wybyłem :-)
Lonas
To ja klikne za Ciebie ;-)

destroyerr : Na stronie autor tej klasy podaje że wystarczy utworzyć plik yml ? chyba że jest jakaś różnica w działaniu tego walidatora w symfony 1.1 i 12 ?
http://snippets.symfony-project.org/snippet/259
mike
Cytat(Lonas @ 23.03.2009, 13:34:42 ) *
Chyba że jest jakaś różnica w działaniu tego walidatora w symfony 1.1 i 1.2 ?
Jest. Podany przez Ciebie validator został napisany pod 1.0. Dzięki kompatybilności wstecznej działa w 1.1 ale w 1.2 już nie zadziała.
Lonas
Czyli dokumentacja niby do 1.2 też nieaktualna ?
http://www.symfony-project.org/book/1_2/10...ustom_validator
mike
Cytat(Lonas @ 23.03.2009, 13:52:06 ) *
Czyli dokumentacja niby do 1.2 też nieaktualna ?
http://www.symfony-project.org/book/1_2/10...ustom_validator
Niestety tak.

Rozwiązanie mojego problemu to 3 klasy:
  1. <?php
  2.  
  3. /**
  4.  * @author Michał Mech
  5.  */
  6. class sfFormProcessable extends sfForm {
  7.  
  8.    public function addProcessError(sfFormProcessError $error) {
  9.        $this->getErrorSchema()->addError($error);
  10.    }
  11. }
  12.  
  13. /**
  14.  * @author Michał Mech <michal.mech@k2.pl>
  15.  */
  16. abstract class sfFormPropelProcessable extends sfFormPropel {
  17.  
  18.    public function addProcessError(sfFormProcessError $error) {
  19.        $this->getErrorSchema()->addError($error);
  20.    }
  21. }
  22.  
  23.  
  24. /**
  25.  * @author Michał Mech <michal.mech@k2.pl>
  26.  */
  27. class sfFormProcessError extends sfValidatorError {
  28.  
  29.    /**
  30.      * @var sfValidatorBase
  31.      */
  32.    protected $validator;
  33.  
  34.    public function __construct($message = null) {
  35.        $this->validator = new sfValidatorPass();
  36.        $this->validator->setMessage('invalid', $message);
  37.  
  38.        parent::__construct($this->validator, 'invalid');
  39.    }
  40. }
  41.  
  42. ?>

Obecnie moje klasy formularzy dziedziczą po sfFormProcessable (lub po sfFormPropelProcessable ) dzięki temu mogę zrobić po prostu:
  1. <?php
  2.  
  3. $form = SampleForm();
  4. try {
  5.    $form->save()
  6. } catch (Exception $e) {
  7.    $form->addProcessError(
  8.        new sfFormProcessError($e->getMessage());
  9.    );
  10. }
  11.  
  12. ?>

A błędy wyświetlą się w formularzu.
Lonas
Czy to powinno być coś w ten deseń ?

  1. <?php
  2. class sfFileImageValidator extends sfValidatorFile
  3. {
  4.  
  5.  protected function configure($options = array(), $messages = array())
  6.  {
  7.    parent::configure($options, $messages);
  8.  
  9.    $this->addOption('max_width');
  10.    $this->addMessage('max_width', 'tttt');
  11.  }
  12.  
  13.  
  14.  protected function doClean($value)
  15.  {
  16.    list($width, $height) = getimagesize($value['tmp_name']);
  17.    
  18.  
  19.    if ($width >  100)
  20.    {
  21.      throw new sfException('My exception message');
  22.    }
  23.  
  24.    return $value;
  25.  }
  26. }
  27. ?>
destroyerr
Mniej więcej coś takiego, tylko klasa wyjątku to sfValidatorError. Zerknij na inne walidatory, to będziesz wiedział jak to zrobić.
Lonas
Walidator działa - wyglada to narazie tak :

  1. <?php
  2. class sfFileImageValidator extends sfValidatorFile
  3. {
  4.  
  5.  protected function configure($options = array(), $messages = array())
  6.  {
  7.    parent::configure($options, $messages);
  8.  
  9.    $this->addOption('max_width');
  10.    $this->addMessage('max_width', 'tttt');
  11.  }
  12.  
  13.  
  14.  protected function doClean($value)
  15.  {
  16.    
  17.    list($width, $height) = getimagesize($value['tmp_name']);
  18.    
  19.  
  20.    if ($this->hasOption('max_width') && $width > $this->getOption('max_width'))
  21.    {
  22.      throw new sfValidatorError($this, 'max_width', array('value' => $value, 'max_width' => $this->getOption('max_width')));
  23.    }
  24.  
  25.    return $value;
  26.  }
  27.  
  28. }
  29. ?>


Jak będzie gotowy wrzuce pełen kod, nie działa mi natatomiast w sytuacji gdy walidacja się powiedzie - walidator nie zwraca obiektu
w sfValidatorFile zwracany jest obiekt

  1. <?php
  2. $class = $this->getOption('validated_file_class');
  3.  
  4.    return new $class($value['name'], $mimeType, $value['tmp_name'], $value['size'], $this->getOption('path'));
  5. ?>


Fatal error: Call to a member function save() on a non-object in C:\Program Files\WebServ\httpd\sf_gallery\lib\symfony\plugins\sfPropelPlugin\lib\form\sfFormPropel.class.php on line 508

jak to powinno być w moim 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.