9
votes

I am embedding a form type into another form type like so

$builder->add('parent', new \Company\Bundle\Form\UserObjects\AParentType);

However when I try and bind the request to the form

if($request->getMethod() == 'POST') {
      $form->bindRequest($request);
}

I get the error

Catchable Fatal Error: Argument 1 passed to Company\Bundle\Entity\UserObjects\User::setParent() must be an instance of Company\Bundle\Entity\UserObjects\AParent, array given, called in /Volumes/Media/Symfony/vendor/symfony/src/Symfony/Component/Form/Util/PropertyPath.php on line 346 and defined in /Volumes/Media/Symfony/src/Company/Bundle/Entity/UserObjects/User.php line 771

It seems like the form is passing the "AParent" object as an array instead of as an entity. Any ideas?

Edited

User.php

    <?php
    // src/Company/Bundle/Entity/UserObjects/Users.php

    namespace Company\Bundle\Entity\UserObjects;

    use Symfony\Component\Security\Core\User\UserInterface;

    use Doctrine\ORM\Mapping as ORM;

    /**
     * @ORM\Entity(repositoryClass="Company\Bundle\Repository\UserObjects\UserRepository")
     * @ORM\Table(name="user")
     * @ORM\HasLifecycleCallbacks()
     */
    class User implements UserInterface, \Serializable
    {
         /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;

         /**
         * @ORM\Column(type="string")
         */
        protected $username;

         /**
         * @ORM\Column(type="string")
         */
        protected $password;

         /**
         * @ORM\Column(type="string")
         */
        protected $securityQuestion;

         /**
         * @ORM\Column(type="string")
         */
        protected $securityAnswer;

         /**
         * @ORM\Column(type="string")
         */
        protected $salt;


        /**
         * @ORM\OneToOne(targetEntity="AParent", inversedBy="user")
         */
        private $parent;







        public function serialize()  
        {  
            return serialize(array(  
                'username'    => $this->getUsername(),  
                'password'    => $this->getPassword(),  
                'salt'        => $this->getSalt(),  
                'roles'       => $this->getRoles(),
            ));  
        } 

        public function unserialize($serializedData)  
        {  
            $unserializedData     = unserialize($serializedData);  

            $this->setUsername(isset($unserializedData['username']) ? $unserializedData['username'] : null);  
            $this->setPassword(isset($unserializedData['password']) ? $unserializedData['password'] : null);  
            $this->setSalt(isset($unserializedData['salt']) ? $unserializedData['salt'] : null); 
        }  

        public function getRoles()
        {
            return array('ROLE_USER');
        }




        public function eraseCredentials()
        {
            return false;
        }

         public function equals(UserInterface $user)
        {
               if ($user->getUsername() != $this->getUsername()) {
                    return false;
                }
                if ($user->getEmail() != $this->getEmail()) {
                    return false;
                }
                return true;
        }

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

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

        public function getUsername()
        {
            return $this->username;
        }

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

        /**
         * Set username
         *
         * @param string $username
         */
        public function setUsername($username)
        {
            $this->username = $username;
        }

        /**
         * Set password
         *
         * @param string $password
         */
        public function setPassword($password)
        {
            $this->password = $password;
        }

        /**
         * Set securityQuestion
         *
         * @param string $securityQuestion
         */
        public function setSecurityQuestion($securityQuestion)
        {
            $this->securityQuestion = $securityQuestion;
        }

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

        /**
         * Set securityAnswer
         *
         * @param string $securityAnswer
         */
        public function setSecurityAnswer($securityAnswer)
        {
            $this->securityAnswer = $securityAnswer;
        }

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

        /**
         * Set salt
         *
         * @param string $salt
         */
        public function setSalt($salt)
        {
            $this->salt = $salt;
        }




        /**
         * Set parent
         *
         * @param Company\Bundle\Entity\UserObjects\AParent $parent
         */
        public function setParent(\DABSquared\ProjectGradesBundle\Entity\UserObjects\AParent $parent)
        {
            $this->parent = $parent;
            if($parent != null) {
                $parent->setUser($this);
            }
        }

        /**
         * Get parent
         *
         * @return Company\Bundle\Entity\UserObjects\AParent 
         */
        public function getParent()
        {
            return $this->parent;
        }


        }
        public function __construct()
        {
        }

    }

AParent.php

    <?php
    // src/Company/Bundle/Entity/UserObjects/AParent.php

    namespace Company\Bundle\Entity\UserObjects;

    use Doctrine\ORM\Mapping as ORM;



    /**
     * @ORM\Entity(repositoryClass="Company\Bundle\Repository\UserObjects\AParentRepository")
     * @ORM\Table(name="parents")
     * @ORM\HasLifecycleCallbacks()
     */
    class AParent
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;


        /**
         * @ORM\OneToOne(targetEntity="User", inversedBy="parent")
         */
         private $user;

                    /**
                     * @ORM\Column(type="string")
                     */
                    protected $zipCode;


        public function __construct()
        {

        }

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

        /**
         * Set user
         *
         * @param Company\Bundle\Entity\UserObjects\User $user
         */
        public function setUser(\Company\Bundle\Entity\UserObjects\User $user)
        {
            $this->user = $user;
        }

        /**
         * Get user
         *
         * @return Company\Bundle\Entity\UserObjects\User 
         */
        public function getUser()
        {
            return $this->user;
        }

                    /**
         * Set zipCode
         *
         * @param string $zipCode
         */
        public function setZipCode($zipCode)
        {
            $this->zipCode = $zipCode;
        }

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



    }

UserType.php

    <?php

    namespace Company\Bundle\Form;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilder;

    use Doctrine\ORM\EntityRepository;

    class UserType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
            $builder
                ->add('username',null,array('label' => 'Username:'))
                ->add('password',null,array('label' => 'Password:'))
                ->add('securityQuestion',null,array('label' => 'Security Question:'))
                ->add('securityAnswer',null,array('label' => 'Security Answer:'))
                ->add('parent', new \Company\Bundle\Form\UserObjects\AParentType);

        }

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

AParentType.php

    <?php

    namespace Company\Bundle\Form\UserObjects;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilder;

    class AParentType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
            $builder
                ->add('zipCode',null,array('label' => 'Zip Code:'));
        }

        public function getName()
        {
            return 'aparenttype';
        }
    }
1
Aren't the parenthesis after the class name mandatory, in your first code snippet?greg0ire
Would also be helpful to see some more code. This doesn't tell us much.Flukey
@greg0ire I do not think so because the form builds and displays fine on the page, but when the form is posted and binder to the User object is when this error occurs.Daniel
@Jamie what more would you like to see, there really isn't that much and I'm not by my computer with the code at the moment.Daniel
Your entity definitions and your form class. Looks like a problem with relations.Flukey

1 Answers

8
votes

You haven't set the data class in your AParentType form. You do that like this:

public function getDefaultOptions(array $options)
{
    return array(
        'data_class' => 'Project\MyBundle\Entity\AParent',
    );
}

For later versions of Symfony, you'll need to use this instead:

use Symfony\Component\OptionsResolver\OptionsResolverInterface;
//...

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Project\MyBundle\Entity\AParent',
    ));
}

Replace this:

->add('parent', new \Company\Bundle\Form\UserObjects\AParentType);

With this:

->add('parent', new AParentType());

because you've already included the namespace.

And if it's one-to-one, which it is, in your form template, you do:

{{ form_row(form.parent.zipCode) }}

Hopefully that should work. Your entity definitions look fine :-)