如何在Symfony 4中覆盖FOSUserBundle的表单

3

我希望覆盖FOSUserBundle的RegistrationType表单,但在registration_content.html.twig模板中遇到了这个错误:

在类“Symfony\Component\Form\FormView”中,既没有属性“firstname”,也没有方法“firstname()”、“getfirstname()”/“isfirstname()”/“hasfirstname()”或“__call()”存在且具有公共访问权限。

这是我的RegistrationType表单:

    class RegistrationType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('firstname');
    }

    public function getParent() {
        return 'fos_user_registration';
    }

    public function getName() {
        return 'app_user_registration';
    }

}

fos_user.yaml:

fos_user:
registration:
    confirmation:
        enabled: true
    form:
        name: app_user_registration
db_driver: orm
user_class: App\Entity\User
firewall_name: main
from_email:
    address: foo@example.com
    sender_name: bar@example.com

用户实体:

class User extends BaseUser {
     //

     /**
     * @ORM\Column(type="string", length=50, nullable=true)
     */
    protected $firstname;
}

registration_content.html.twig:

    {{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register', 'id': 'form-sign-up'}}) }}
                <div class="form-group form-group--float form-group--centered">
                    {{ form_widget(form.firstname, {'attr': {'class': 'form-control'}}) }}
                    <label>{{ 'firstname'|trans }}</label>
                    <i class="form-group__bar"></i>
                </div>
{{ form_end(form) }}

在我的配置服务中,我已经放置了以下内容:
app.form.registration:
        class: App\Form\RegistrationType
        tags:
            - { name: form.type, alias: app_user_registration }

不确定您在将User类包含在问题中时削减了多少内容,但是您是否为其他属性添加了getter和setter?由于$firstname是受保护的,因此您需要有一个getFirstname和一个setFirstname方法。 - dlondero
@dlondero 是的,我已经添加了setter方法。 - Mintendo
缓存清除了吗?你懂的... - dlondero
没有任何东西,即使使用了cache:clear。 - Mintendo
4个回答

5

工作示例

Symfony 4.2.3 | friendsofsymfony/user-bundle v2.1.2

通过我们自己的类覆盖FOSUserBundle注册表单,并删除“用户名”字段,以便进行示例。

从您的Symfony根目录开始:

  1. mkdir ./src/Form/Type
  2. cp ./vendor/friendsofsymfony/user-bundle/Form/Type/RegistrationFormType.php
  3. 编辑./config/packages/fos_user.yaml
# fos_user.yaml
fos_user:

    #... other configurations...

    registration:
        form:
            type: App\Form\Type\RegistrationType
  1. Edit ./src/Form/Type/RegistrationFormType.php
// Our specific example. edit this as you please...
<?php

namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseRegistrationFormType;

class RegistrationFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->remove('username');
    }
    public function getParent() {
        return BaseRegistrationFormType::class;
    }
}

注意:由于我们的示例仅删除单个字段,因此我们将删除不需要更改的代码,并添加以下方法以保持简单:

public function getParent() {
    return BaseRegistrationFormType::class;
}
  • 本信息的大部分内容来自@Gabriel Deschamps@Robert Saylor的答案。
  • 我没有研究getParent方法,但它似乎是从原始的RegistrationFormType.php继承的,并在buildForm方法中简单添加了我们所做的更改。

3
我在按照官方教程https://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html时遇到了相同的问题。我无法解释为什么会出现这个问题,但似乎与别名有关。无论如何,在Symfony4和Symfony 3.4中都无法使其正常工作!
我使用以下代码绕过了这个问题:
class RegistrationType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstname');
    }

    public function getParent() {
        return 'FOS\UserBundle\Form\Type\RegistrationFormType';
    }

}

然后将以下行添加到您的fos_user.yaml文件中:
fos_user:
    registration:
        form:
            type: App\Form\Type\RegistrationType

我希望这能有所帮助,直到有人找到让它按预期运行的方法。


2
  1. 在你的src目录下创建一个名为Form的文件夹。
  2. 创建一个名为RegistrationFormType.php的文件,并添加以下内容:

    namespace App\Form;

    use Symfony\Component\Form\AbstractType;

    use Symfony\Component\Form\FormBuilderInterface;

    use FOS\UserBundle\Form\Type\RegistrationFormType as BaseRegistrationFormType;

    class RegistrationFormType extends AbstractType

    {

public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder

            ->add('first');

        $builder
            ->add('last');

    }

    public function getParent()
    {
        return BaseRegistrationFormType::class;
    }
}

假设您已向用户实体添加了两个新字段,并且运行了Doctrine迁移以添加新字段。 提示:将这些字段设置为可为空,这样您就不需要使用FOS命令行工具。
在config/packages中的fos_users.yaml文件中添加以下内容:
registration:
form:

    type: App\Form\RegistrationFormType
  1. Add the following to services.yaml:

    app.form.registration:

    class: App\Form\RegistrationFormType
    

刷新您的表单,新字段将出现在表单中。


0
在我的情况下,我和Robert Saylor做了同样的事情,但是我编辑了这个:
public function getBlockPrefix()
{
    return 'app_user_registration';
}

对我来说,那很好用!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接