Witam,
od pewnego czasu realizuje pewien projekt przy pomocy frameworka "Symfony 4". Po raz kolejny w wyżej wymienionym projekcie spotykam się z problemem walidacji. Pierwszy problem polegał na tym, iż zadeklarowane za pomocą adnotacji w encji walidatory uruchamiały się nawet w przypadku gdy podanego pola nie było w input formie. Ten problem udało mi się obejść za pomocą grup np.
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank(groups={"register", "password_reset"})
* @AcmeAssert\ContainsAlphanumeric(groups={"register", "password_reset"})
*/
//
private $password;
Za drugim razem problem dotyczył plików podpiętych do encji np. zdjęć do użytkownika, gdzie zgodnie z dokumentacją chciałem, aby w pole image było typu string i zapisywało w bazie danych tylko nazwę i rozszerzenie obrazu. Jednak pomimo, iż w dokumentacji korzystano z Assert/File w ten sposób:
/**
* @ORM\Column(type="string", length=255, nullable=true)
*@Assert\File(mimeTypes={ "image/png", "image/jpeg"})
*
*/
private $image;
To znów pojawił się problem, iż przy zapisie danych do bazy wszystko było w porządku, lecz przy próbie edycji za każdym razem gdy tylko wcześniej zostało ustawione jakieś zdjęcie, pomimo iż wartość mapped została ustawiona na false ciągle wyłapywał że wartość pola to przykładowo "nazwa.jpg" a nie plik.
$image = $loggedUser->getImage();
$form = $this->createFormBuilder($loggedUser)
->add('email', EmailType::class, array('attr' => array('class' => 'email-form', 'placeholder' => 'E-mail' ),'label' => false))
->add('imageF', FileType::class, array('mapped' => false, 'data_class' => null, 'required' => false, 'attr' => array('class' => 'image-form'),'label' => false))
->add('save', SubmitType::class, array('label' => 'Change'))
->getForm();
To mi się udało obejść może niezbyt ładnie za pomocą zakomentowania Assert/file i stworzenia w klasie obsługującej upload zdjęć funkcji validate:
public function validateFile(UploadedFile $file)
{
$ext = $file->guessExtension();
$conditions =['png', 'jpg', 'jpeg'];
if(in_array($ext,$conditions) )
{
//$iniVal = ini_get('upload_max_filesize');//2mb
//$mbSize = str_replace('M', '', $iniVal);
$byteSize = $this->maxSize * 1048576;
if ($file->getSize() < $byteSize) {
return true;
}
throw new Exception("Your file its too large!!");
}
throw new Exception("Wrong extension file!!");
}
Jednak teraz mam kolejny problem, ponieważ chcę za pomocą formularza umożliwić zmianę hasła i walidacja działa tylko wtedy gdy stworzę nowy obiekt klasy User ($user= new User ()) co według mnie jest głupie żeby tworzyć nowy obiekt tylko po to by przetestować poprawność wprowadzonego hasła (pomijając już fakt że musiałbym każde inne pole typu username, e-mail itp znów wyłączać dla danej operacji). Za to jeśli próbuję do formularza wrzucić dane danego użytkownika,którego hasło ma ulec zmianie to walidacja hasła w ogóle nie działa. Poniżej kod operacji zmiany hasła:
public function userPassReset(Request $req,Crypt $cryp,Register $reg, $token)
{
$crname = $cryp->decrypt($token);
$user_rep = $this->getDoctrine()->getRepository(User::class);
$user = $user_rep->findOneBy(['username' => $crname]);
$form = $this->createFormBuilder($user)
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array( 'attr' => array('placeholder' => 'New Password'), 'label' => false),
'second_options' => array('attr' => array('placeholder' => 'Repeat Password' ),'label' => false),
'error_bubbling' => true
))
->add('save', SubmitType::class, array('label' => 'Change'))
->getForm();
$form->handleRequest($req);
if($form->isSubmitted() && $form->isValid())
{
$reg->newPass($user, $form['password']->getData());
//return $this->redirectToRoute('login');
}
/// i funkcja newPass
public function newPass($user, $newPass)// change pass after reset
{
$user->setPassword(
$this->passwordEncoder->encodePassword($user, $newPass)
);
$this->om->persist($user);
$this->om->flush();
}
Czy istnieje jakieś lepsze rozwiązanie np. poprzez zdefiniowanie warunków walidacji wewnątrz formularza lub w jakiś inny bardziej przyjazny sposób?? Pytam tutaj, ponieważ od dłuższego czasu próbuję coś lepszego znaleźć, lecz póki co bez skutecznie. Z góry bardzo dziękuje za wszystkie rady.
Pozdrawiam Krzysztof