FOSUserBundle form extension

I've overridden successfully FOSUserbundle's User class adding a bunch of properties. But When I tried to add 'types' property as you can see that below, I'm having the following exception:

Neither the property "types" nor one of the methods "addTyp()"/"removeTyp()", "addType()"/"removeType()", "setTypes()", "types()", "__set()" or "__call()" exist and have public access in class "AdvertprojectUserBundleEntityUser".

Type is a separate entity with a ManyToMany relationship with my custumized Entity/User.

The idea is to insert a radio button form inside the main form. I've read many of the answers provided here for similar error message, but nothing works. Actually my case is similar to this (answer provided by @Mick then). But the advices provided don't work in my case because I did exactly what was recommended there. Can anyone help me out with this? Note that the form is being rendered properly with the radio button form, and the exception is being returned after I hit submit button.

Advertproject/UserBundle/Entity/User:

namespace AdvertprojectUserBundleEntity;

use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping as ORM;
use FOSUserBundleModelUser as BaseUser;
use SymfonyComponentValidatorConstraints as Assert;
/**
* User
*
* @ORMTable(name="fos_user")
*@ORMEntity(repositoryClass="AdvertprojectUserBundleEntityUserRepository")            

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

   /**
   * @ORMColumn(type="string", length=255)
   *
   * @AssertNotBlank(message="Please enter the company name.", groups={"Registration", "Profile"})
   * @AssertLength(
   *     min=3,
   *     max=255,
   *     minMessage="The company name is too short.",
   *     maxMessage="The company name is too long.",
   *     groups={"Registration", "Profile"}
   * )
   */
   protected $companyName;

   /**
   * @ORMColumn(type="string", length=255)
   *
   * @AssertNotBlank(message="Please enter your phone.", groups={"Registration", "Profile"})
   * @AssertLength(
   *     min=8,
   *     max=255,
   *     minMessage="The phone value is too short.",
   *     maxMessage="The phone value is too long.",
   *     groups={"Registration", "Profile"}
   * )
   */
   protected $phone;

   /**
   * @ORMColumn(type="string", length=255)
   *
   * @AssertNotBlank(message="Please add details about the person we can contact.", groups={"Registration", "Profile"})
   * @AssertLength(
   *     min=30,
   *     max=255,
   *     minMessage="The details info is too short.",
   *     maxMessage="The details info is too long.",
   *     groups={"Registration", "Profile"}
   * )
   */
   protected $details;

   /**
   * @var
   * @ORMManyToMany(targetEntity="AdvertprojectUserBundleEntityType", cascade={"persist"})
   * @ORMJoinColumn(nullable=false)
   */
   protected $types;

/**
 * @var DateTime
 *
 * @ORMColumn(name="date", type="datetime")
 */
private $date;

/**
 * @ORMColumn(name="updated_at", type="datetime", nullable=true)
 */
private $updatedAt;


public function __construct()
{
    parent::__construct();
    $this->date = new Datetime();
    $this->types = new ArrayCollection();
}

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

/**
 * Set companyName
 *
 * @param string $companyName
 * @return User
 */
public function setCompanyName($companyName)
{
    $this->companyName = $companyName;

    return $this;
}

/**
 * Get companyName
 *
 * @return string 
 */
public function getCompanyName()
{
    return $this->companyName;
}

/**
 * Set phone
 *
 * @param string $phone
 * @return User
 */
public function setPhone($phone)
{
    $this->phone = $phone;

    return $this;
}

/**
 * Get phone
 *
 * @return string 
 */
public function getPhone()
{
    return $this->phone;
}

/**
 * Set details
 *
 * @param string $details
 * @return User
 */
public function setDetails($details)
{
    $this->details = $details;

    return $this;
}

/**
 * Get details
 *
 * @return string 
 */
public function getDetails()
{
    return $this->details;
}

public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);

    return $this;
}

public function setEmailCanonical($emailCanonical)
{
    $this->emailCanonical = $emailCanonical;
    $this->usernameCanonical = $emailCanonical;
}

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

/**
 * Set date
 *
 * @param DateTime $date
 * @return User
 */
public function setDate($date)
{
    $this->date = $date;

    return $this;
}

/**
 * Get date
 *
 * @return DateTime 
 */
public function getDate()
{
    return $this->date;
}

/**
 * Set updatedAt
 *
 * @param DateTime $updatedAt
 * @return User
 */
public function setUpdatedAt($updatedAt)
{
    $this->updatedAt = $updatedAt;

    return $this;
}

/**
 * Get updatedAt
 *
 * @return DateTime 
 */
public function getUpdatedAt()
{
    return $this->updatedAt;
}

/**
 * Add Type
 *
 * @param AdvertprojectUserBundleEntityType $type
 * @return User
 */
public function addType(Type $type)
{
    $this->types[] = $type;
    return $this;
}

/**
 * Remove types
 *
 * @param AdvertprojectUserBundleEntityType $types
 */
public function removeType(Type $types)
{
    $this->types->removeElement($types);
}
}

Advertproject/UserBundle/Form/Type/RegistrationFormType:

class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('companyName', 'text')
        ->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
        ->add('phone', 'text')
        ->add('plainPassword', 'repeated', array(
            'type' => 'password',
            'options' => array('translation_domain' => 'FOSUserBundle'),
            'first_options' => array('label' => 'form.password'),
            'second_options' => array('label' => 'form.password_confirmation'),
            'invalid_message' => 'fos_user.password.mismatch',
        ))
        ->add('details', 'textarea')
        ->add('types', 'entity', array(
            'class' => 'APUserBundle:Type',
            'property' => 'name',
            'required' => true,
            'expanded' => true,
            'multiple' => false,
        ))
    ;
}

Advertproject/UserBundle/Entity/Type:

namespace AdvertprojectUserBundleEntity;

use DoctrineORMMapping as ORM;

/**
 * Type
 *
 * @ORMTable(name="type")
 * @ORMEntity(repositoryClass="AdvertprojectUserBundleEntityTypeRepository")
 */
class Type
{
    /**
     * @var integer
     *
     * @ORMColumn(name="id", type="integer")
     * @ORMId
     * @ORMGeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORMColumn(name="name", type="string", length=255)
     */
    private $name;


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

    /**
     * Set name
     *
     * @param string $name
     * @return Type
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }
}

I am still missing your Type entity.

Try these things (one by one and after each one check what might help):

  • Take over one of doctrine's examples for ManyToMany relations (choose between unidirectional or bidirectional). Only change the annotations to @ORM... annotations.

  • run following commands app/console doctrine:cache:clear-metadata app/console doctrine:cache:clear-result app/console doctrine:cache:clear-query app/console cache-clear app/console cache-clear --env=prod

  • restart (if possible) your webserver


  • in your form type you are using entity Type as pack of choices for user.

    U don't have setTypes function

    1) $types is not a field in your database - mises @ORMColumn(type="string", length=255) (remove that many-to-nothing relation, add column annotation)

    2) in user entity you want to store one value or multiple?

    if one, just do as I propose above.

    If each user can have many items selected - your Type entity use as list of choices, and store data in entity UserChoices. then connect UserChoices as Many-To-One to User entity.

    attributes in clases done for connecting between entities are not always fields in database, they pointing fields which store data

    链接地址: http://www.djcxy.com/p/69386.html

    上一篇: 在Doctrine 2.6中覆盖特征属性的关联映射

    下一篇: FOSUserBundle表单扩展