Как расширить форму регистрации дополнительными полями в FOSUserBundle и Symfony3

Я изучаю symfony3 framework. Теперь я построил проект, который содержит две сущности: User и Catalog. Сущность каталога для дополнительных данных компании (название компании, адрес и так далее) — это как визитная карточка. Один пользователь (но не все) связан только с одной визитной карточкой (Catalog entity), поэтому я решил использовать две отдельные сущности. Некоторые пользователи имеют доступ, например, к бэкэнду, а другие имеют возможность добавлять и управлять своей визитной карточкой.
Я хочу, чтобы пользователь мог заполнить данные своей компании во время регистрации. Я использую FOSUserBundle для сущности пользователя. В настоящее время у меня есть регистрационная форма работает, но я застрял и нужна ваша помощь с внедрением моей формы CatalogType.

Форма CatalogType:

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;

class CatalogType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('name')
        ->add('address')
        ->add('city')
        ->add('province')
        ->add('postcode')
        ->add('telephone')
        ->add('fax')
        ->add('mobile')
        ->add('email')
        ->add('webpage')
        ->add('misc')        
        ;
    }

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

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'app_user_registration';
    }

}

Сущность пользователя:

use DoctrineORMMapping as ORM;
use FOSUserBundleModelUser as BaseUser;

/**
 * User
 *
 * @ORMTable(name="user")
 * @ORMEntity(repositoryClass="AppBundleRepositoryUserRepository")
 */
class User extends BaseUser
{
    /**
     * @var int
     *
     * @ORMColumn(name="id", type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
    * @var
    * 
    * @ORMOneToMany(targetEntity="Comment", mappedBy="user")
    */
    private $comments;

    /**
    * @var
    * 
    * @ORMOneToOne(targetEntity="Catalog", mappedBy="user")
    */
    private $catalog;

    public function __construct()
    {
        parent::__construct();

        $this->comments = new DoctrineCommonCollectionsArrayCollection();
    }


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add comment
     *
     * @param AppBundleEntityComment $comment
     *
     * @return User
     */
    public function addComment(AppBundleEntityComment $comment)
    {
        $this->comments[] = $comment;

        return $this;
    }

    /**
     * Remove comment
     *
     * @param AppBundleEntityComment $comment
     */
    public function removeComment(AppBundleEntityComment $comment)
    {
        $this->comments->removeElement($comment);
    }

    /**
     * Get comments
     *
     * @return DoctrineCommonCollectionsCollection
     */
    public function getComments()
    {
        return $this->comments;
    }

    /**
     * Set catalog
     *
     * @param AppBundleEntityCatalog $catalog
     *
     * @return User
     */
    public function setCatalog(AppBundleEntityCatalog $catalog = null)
    {
        $this->catalog = $catalog;

        return $this;
    }

    /**
     * Get catalog
     *
     * @return AppBundleEntityCatalog
     */
    public function getCatalog()
    {
        return $this->catalog;
    }
}

Сущность каталога

<?php

namespace AppBundleEntity;

use DoctrineORMMapping as ORM;

/**
 * Catalog
 *
 * @ORMTable(name="catalog")
 * @ORMEntity(repositoryClass="AppBundleRepositoryCatalogRepository")
 */
class Catalog
{
// ... definition a lot of private variables ...
/**
* @var
* 
* @ORMOneToOne(targetEntity="User", inversedBy="catalog")
* @ORMJoinColumn(name="user_id", nullable=true)
*/
private $user;

// ...

/**
 * Set user
 *
 * @param AppBundleEntityUser $user
 *
 * @return Catalog
 */
public function setUser(AppBundleEntityUser $user = null)
{
    $this->user = $user;

    return $this;
}

/**
 * Get user
 *
 * @return AppBundleEntityUser
 */
public function getUser()
{
    return $this->user;
}

Файл конфигурации служб:

// app/config/services.yml
services:
    app.form.registration:
        class: AppBundleFormCatalogType
        tags:
            - { name: form.type, alias: app_user_registration }

Когда я пытаюсь отобразить форму регистрации под http://localhost:8000/register/
Я получаю ошибку:

Ни свойство «name» ни один из методов » getName()»,
«name ()», «isName ()», «hasName ()», «__get () » существуют и имеют public
доступ в классе «AppBundleEntityUser».

Я знаю, где проблема, но я не знаю, как правильно ее решить, так что было бы здорово, если кто-то может помочь мне, где я должен искать решения или как он должен быть решен.
Спасибо.

1 ответ

  1. CatalogType не должен расширять RegistrationFormType. Это должен быть тип формы для AppBundle\Entity\Catalog.
    Вы должны сделать тип формы, который основан на классе пользователя (подкласс FOS\UserBundle\Model\User), и который встраивает форму CatalogType.

    class UserType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('...', ...)
                    ->add('tasks', CollectionType::class, array(
                        'entry_type' => CatalogType::class,
                        ...
                    ));
                    ...
            ;
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'AppBundle\Entity\User',
            ));
        }
    
        public function getBlockPrefix()
        {
            return 'app_user_registration';
        }
    }
    
    
    class CatalogType extends AbstractType
    {
        /**
         * {@inheritdoc}
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
            ->add('name')
            ->add('address')
            ->add('city')
            ->add('province')
            ->add('postcode')
            ->add('telephone')
            ->add('fax')
            ->add('mobile')
            ->add('email')
            ->add('webpage')
            ->add('misc')        
            ;
        }
     ...
    }
    

    Подробнее о внедрении форм: https://symfony.com/doc/current/form/form_collections.html
    Подробнее о переопределении форм FosUserBundle: http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html