【发布时间】:2020-06-03 18:47:08
【问题描述】:
我正在尝试使用 Symfony 的所有功能来构建一个站点。我已经有 2 年的 Symfony 经验,但我第一次尝试使用自定义表单类型的概念来创建特定的注册表单。我已经有一个基本用户的注册表单,但现在我想为经营酒店的经理创建另一个注册表。
我已经创建了一个名为 RegistrationFormType 的表单类型和另一个名为 HotelType 的表单类型。我的事情是我想在一个表单中使用这两种表单类型。但我不断收到一个例外,上面写着
既不是“用户”属性也不是“getUser()”方法之一, “user()”、“isUser()”、“hasUser()”、“__get()” 存在并公开 在“App\Entity\User”类中访问
我遵循了 Symfony 官方文档中关于自定义表单类型的内容。
我制作了这个表单类型 RegistrationHotelFormType,它由另一个表单 RegistrationFormType 组成,在其他地方用作基本用户创建帐户的表单和 Symfony 自身生成的 HotelType。
<?php
namespace App\Form;
use App\Entity\User;
use App\Form\HotelType;
use App\Form\RegistrationFormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Regex;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Validator\Constraints\File;
class RegistrationHotelFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user', RegistrationFormType::class, ['mapped' => false])
->add('hotel', HotelType::class, ['mapped' => false])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
上面的方法可以工作,但在 Symfony 文档中,我不需要将映射参数设置为 false,因为我知道我希望将表单值分配给酒店和用户的对象字段。我怎样才能完成这项工作? (https://symfony.com/doc/current/form/create_custom_field_type.html#creating-form-types-created-from-scratch)。
注册表格类型:
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Regex;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Validator\Constraints\File;
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class, ['error_bubbling'=>true, 'label' => 'Email', 'attr' => ['type'=>'text','class'=>'form-control', 'placeholder'=>'Email', 'aria-label'=>"Username", 'aria-describedby'=>"basic-addon1"]])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'label' => 'Mot de passe',
'attr' => ['error_bubbling'=>true,
'type'=>'text',
'class'=>'form-control',
'placeholder'=>'Mot de passe',
'aria-label'=>"Username",
'aria-describedby'=>"basic-addon1"],
'mapped' => false,
'constraints' => [
new NotBlank([
'message' => 'Mot de passe requis',
]),
new Length([
'min' => 8,
'minMessage' => 'Le mot de passe doit avoir au moins {{ limit }} caractères',
// max length allowed by Symfony for security reasons
'max' => 128,
'maxMessage' => 'Le mot de passe ne doit pas dépasser {{ limit }} caractères',
]),
// new Regex([
// 'pattern' => '/^\S*(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/',
// 'message' => 'Le mot de passe doit contenir au moins 1 lettre et 1 chiffre',
// ])
],
])
->add('firstname', TextType::class, ['error_bubbling'=>true, 'label' => 'Prénom', 'attr' => ['type'=>'text','class'=>'form-control', 'placeholder'=>'Prénom', 'aria-label'=>"Username", 'aria-describedby'=>"basic-addon1"]])
->add('surname', TextType::class, ['error_bubbling'=>true, 'label' => 'Nom', 'attr' => ['type'=>'text','class'=>'form-control', 'placeholder'=>'Nom', 'aria-label'=>"Username", 'aria-describedby'=>"basic-addon1"]])
->add('phoneNumber', TextType::class, ['error_bubbling'=>true, 'label' => 'Téléphone', 'attr' => ['type'=>'text','class'=>'form-control', 'placeholder'=>'Téléphone', 'aria-label'=>"Username", 'aria-describedby'=>"basic-addon1"]])
->add('city', TextType::class, ['error_bubbling'=>true, 'label' => 'Ville', 'attr' => ['type'=>'text','class'=>'form-control', 'placeholder'=>'Ville', 'aria-label'=>"Username", 'aria-describedby'=>"basic-addon1"]])
->add('termsAccepted', CheckboxType::class, [
'error_bubbling'=>true,
'mapped' => false,
'constraints' => new IsTrue(),
'attr' => ['type'=>"checkbox", 'class'=>"form-check-input"]
])
->add('resumePDF', FileType::class, [
'error_bubbling'=>true,
'label' => 'CV (Fichier PDF)',
'mapped' => false,
'required' => true,
'constraints' => [
new File([
'maxSize' => '1024k',
'mimeTypes' => [
'application/pdf',
'application/x-pdf',
],
'mimeTypesMessage' => 'Téléchargez un fichier PDF valide',
])
],
'attr' => ['type'=>"file", 'class'=>"custom-file-input"]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
酒店类型
<?php
namespace App\Form;
use App\Entity\Hotel;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class HotelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('address');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Hotel::class,
]);
}
}
RegistrationController.php
/**
* @Route("/inscription-hotel", name="app_register_hotel")
*/
public function registerHotel(Request $request, UserPasswordEncoderInterface $passwordEncoder, \Swift_Mailer $mailer): Response
{
$session = new Session();
// $session->start();
$user = new User();
$form = $this->createForm(RegistrationHotelFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
}
return $this->render('registration/register-hotel.html.twig', [
'registrationForm' => $form->createView(),
]);
}
提前感谢您的帮助
【问题讨论】:
-
这是因为您的酒店注册表单类型正在寻找一个名为 user ($user->user) 的属性以传递给注册表单类型。除非您有一个名为 $user->hotel 的属性,否则您可能会遇到与酒店相同的问题。您可能需要一个 RegisteredUser 实体,其中包含 User 和 Hotel 实体。