Search code examples
phpsymfonydoctrine-ormsymfony-formssymfony-2.2

How to map an Entity to a form in Symfony 2


I have a problem using Symfony 2. When I try to populate a form with data coming from an Entity I get this error:

"The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class DateTime. You can avoid this error by setting the "data_class" option to "DateTime" or by adding a view transformer that transforms an instance of class DateTime to scalar, array or an instance of \ArrayAccess."

I haven't much experience with Symfony 2. To create the Entities I am using YAML option.

Thanks.

The controller code:

public function editAction($id)
{
    $em = $this->getDoctrine()->getManager();
    $candidate = $em->getRepository('OUProjectBundle:Candidate')->findOneById($id); 
    $form = $this->createForm(new CandidateType(), $candidate);

    return $this->render('MyProjectBundle:Candidate:new.html.twig', array(
        'form'   => $form->createView(),
    ));
 }

The CandidateType class:

namespace My\ProjectBundle\Form;

use Symfony\Component\Form\AbstractType;
use My\ProjectBundle\Entity\Candidate;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;

class CandidateType extends AbstractType
{

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

        $builder->add('name', 'text', array('label'=>'Name:'));
        $builder->add('surname', 'text', array('label'=>'Surname:'));
        $builder->add('email', 'text', array('label'=>'Email:'));        
        $builder->add('phone', 'text', array('label'=>'Telephone:'));
        $builder->add('DOB', 'text', array('label'=>'Date of Birth:'));
        $builder->add('address', 'text', array('label'=>'Address'));
        $builder->add('town', 'text', array('label'=>'Town:'));
        $builder->add('city', 'text', array('label'=>'City:'));        
        $builder->add('post_code', 'text', array('label'=>'Post Code:'));
        $builder->add('file', 'file', array('label' => 'CV file (.docx)', 'required' => true));

    }

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

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'My\ProjectBundle\Entity\Candidate',
        );
    }
}

The entity:

namespace OU\ProjectBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use My\ProjectBundle\Utils\DocReader;

/**
 * Candidate
 */
class Candidate
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var string
     */
    private $surname;

    /**
     * @var \DateTime
     */
    private $dob;

    /**
     * @var string
     */
    private $phone;

    /**
     * @var string
     */
    private $address;

    /**
     * @var string
     */
    private $town;

    /**
     * @var string
     */
    private $city;

    /**
     * @var string
     */
    private $post_code;

    /**
     * @var string
     */
    private $cv_text;

    /**
     * @var string
     */
    private $cv_file;

    /**
     * @var \DateTime
     */
    private $createdAt;

    /**
     * @var \DateTime
     */
    private $updatedAt;

    /**
     * @var \DateTime
     */
    private $deletedAt;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $skill;
    public $file;    

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->skill = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

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

        return $this;
    }

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

    /**
     * Set surname
     *
     * @param string $surname
     * @return Candidate
     */
    public function setSurname($surname)
    {
        $this->surname = $surname;

        return $this;
    }

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

    /**
     * Set dob
     *
     * @param \DateTime $dob
     * @return Candidate
     */
    public function setDob($dob)
    {
        $this->dob = new \DateTime($dob);

        return $this;
    }

    /**
     * Get dob
     *
     * @return \DateTime 
     */
    public function getDob()
    {
        return $this->dob;
    }

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

        return $this;
    }

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

    /**
     * Set address
     *
     * @param string $address
     * @return Candidate
     */
    public function setAddress($address)
    {
        $this->address = $address;

        return $this;
    }

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

    /**
     * Set town
     *
     * @param string $town
     * @return Candidate
     */
    public function setTown($town)
    {
        $this->town = $town;

        return $this;
    }

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

    /**
     * Set city
     *
     * @param string $city
     * @return Candidate
     */
    public function setCity($city)
    {
        $this->city = $city;

        return $this;
    }

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

    /**
     * Set post_code
     *
     * @param string $postCode
     * @return Candidate
     */
    public function setPostCode($postCode)
    {
        $this->post_code = $postCode;

        return $this;
    }

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

    /**
     * Set cv_text
     *
     * @param string $cvText
     * @return Candidate
     */
    public function setCvText($cvText)
    {
        $this->cv_text = $cvText;

        return $this;
    }

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

    /**
     * Set cv_file
     *
     * @param string $cvFile
     * @return Candidate
     */
    public function setCvFile($cvFile)
    {
        $this->cv_file = $cvFile;

        return $this;
    }

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

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Candidate
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime 
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

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

        return $this;
    }

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

    /**
     * Set deletedAt
     *
     * @param \DateTime $deletedAt
     * @return Candidate
     */
    public function setDeletedAt($deletedAt)
    {
        $this->deletedAt = $deletedAt;

        return $this;
    }

    /**
     * Get deletedAt
     *
     * @return \DateTime 
     */
    public function getDeletedAt()
    {
        return $this->deletedAt;
    }

    /**
     * Add skill
     *
     * @param \My\ProjectBundle\Entity\Skill $skill
     * @return Candidate
     */
    public function addSkill(\My\ProjectBundle\Entity\Skill $skill)
    {
        $this->skill[] = $skill;

        return $this;
    }

    /**
     * Remove skill
     *
     * @param \My\ProjectBundle\Entity\Skill $skill
     */
    public function removeSkill(\My\ProjectBundle\Entity\Skill $skill)
    {
        $this->skill->removeElement($skill);
    }

    /**
     * Get skill
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSkill()
    {
        return $this->skill;
    }
    /**
     * @ORM\PrePersist
     */
    public function preUpload()
    {
      if (null !== $this->file) {
        // do whatever you want to generate a unique name
          $extension = $this->file->guessExtension();
          if($extension === "zip") $extension = "docx";
          $this->setCvFile(uniqid().'.'.$extension);
          // if there is an error when moving the file, an exception will
          // be automatically thrown by move(). This will properly prevent
          // the entity from being persisted to the database on error
          $this->file->move($this->getUploadRootDir(), $this->cv_file);
          $this->setCvText(DocReader::readDocxFile($this->getAbsolutePath()));
      }
    }

    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
      if(!$this->getCreatedAt())
      {
        $this->createdAt = new \DateTime();
      }
    }

    /**
     * @ORM\PreUpdate
     */
    public function setUpdatedAtValue()
    {
        $this->updatedAt = new \DateTime();
    }

    /**
     * @ORM\PostPersist
     */
    public function upload()
    {
      if (null === $this->file) {
        return;
      }
      unset($this->file);
    }

    /**
     * @ORM\PostRemove
     */
    public function removeUpload()
    {
      if ($file = $this->getAbsolutePath()) {
        unlink($file);
      }
    }

    /**
     * @ORM\PostRemove
     */
    public function setDeletedAtValue()
    {
      if(!$this->getDeletedAt())
      {
        $this->deletedAt = new \DateTime();
      }
    }

    protected function getUploadDir()
    {
        return 'uploads/cvs';
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    public function getWebPath()
    {
        return null === $this->getCvFile() ? null : $this->getUploadDir().'/'.$this->getCvFile();
    }

    public function getAbsolutePath()
    {
        return null === $this->getCvFile()? null : $this->getUploadRootDir().'/'.$this->getCvFile();
    }    
    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $skill_candidate;


    /**
     * Add skill_candidate
     *
     * @param \My\ProjectBundle\Entity\SkillCandidate $skillCandidate
     * @return Candidate
     */
    public function addSkillCandidate(\My\ProjectBundle\Entity\SkillCandidate $skillCandidate)
    {
        $this->skill_candidate[] = $skillCandidate;

        return $this;
    }

    /**
     * Remove skill_candidate
     *
     * @param \My\ProjectBundle\Entity\SkillCandidate $skillCandidate
     */
    public function removeSkillCandidate(\My\ProjectBundle\Entity\SkillCandidate $skillCandidate)
    {
        $this->skill_candidate->removeElement($skillCandidate);
    }

    /**
     * Get skill_candidate
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSkillCandidate()
    {
        return $this->skill_candidate;
    }

    public function __toString()
    {
      return $this->getName().' '.$this->getSurname();
    }    
    /**
     * @var string
     */
    private $email;


    /**
     * Set email
     *
     * @param string $email
     * @return Candidate
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

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

Solution

  • In your CandidateType class, field DOB as text type, in entity it's in datetime format you can use something like this

    $builder->add('DOB', 'date', array('input'  => 'datetime','label'=>'Date of Birth:'));
    

    please refer this date Field Type manual