当上传我的文件的表单嵌入另一个表单时,似乎不会触发我的生命周期回调。如果上传表单独立,则会触发生命周期回调。
我有一个创建“用户”实体的表单,对于这个用户,我与具有生命周期回调的'ProfilePicture'实体有一对一的关系,我想在同一表单上上传profilepicture文件。我按照“如何处理文件上传”的教程,但没有解释如何处理嵌入式表格。
用户类型
<?php
namespace CashBack\AdminBundle\Form\Type;
use CashBack\DefaultBundle\Entity\ProfilePicture;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/* additional fields that should not be saved in this object need ->add('agreeWithTerms', null,array('mapped' => false))*/
$builder
->add('id','hidden',array('mapped' => false))
->add('username')
->add('password')
->add('firstname')
->add('lastname')
->add('email')
->add('gender')
->add('dateOfBirth','birthday')
->add('customrole')
->add('profilepicture', new ProfilePictureType())
->add('save', 'submit');
}
/* Identifier */
public function getName()
{
return 'User';
}
/* Makes sure the form doesn't need to guess the date type */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CashBack\DefaultBundle\Entity\User',
'cascade_validation' => true,
));
}
}
ProfilePictureType
<?php
namespace CashBack\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProfilePictureType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/* additional fields that should not be saved in this object need ->add('agreeWithTerms', null,array('mapped' => false))*/
$builder
->add('id','hidden',array('mapped' => false))
->add('file','file');
}
/* Identifier */
public function getName()
{
return 'ProfilePicture';
}
/* Makes sure the form doesn't need to guess the date type */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CashBack\DefaultBundle\Entity\ProfilePicture',
));
}
}
ProfilePicture实体
<?php
namespace CashBack\DefaultBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class ProfilePicture
{
/**
* @var integer
*
* @ORM\Column(name="Id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $path;
public function getAbsolutePath()
{
return null === $this->path
? null
: $this->getUploadRootDir() . '/' . $this->path;
}
public function getWebPath()
{
return null === $this->path
? null
: $this->getUploadDir() . '/' . $this->path;
}
protected function getUploadRootDir()
{
// the absolute directory path where uploaded
// documents should be saved
return __DIR__ . '/../../../../web/' . $this->getUploadDir();
}
protected function getUploadDir()
{
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'uploads/documents';
}
/**
* @Assert\File(maxSize="6000000")
*/
private $file;
private $temp;
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
// do whatever you want to generate a unique name
$filename = sha1(uniqid(mt_rand(), true));
$this->path = $filename . '.' . $this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
// 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->getFile()->move($this->getUploadRootDir(), $this->path);
// check if we have an old image
if (isset($this->temp)) {
// delete the old image
unlink($this->getUploadRootDir() . '/' . $this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set path
*
* @param string $path
*
* @return ProfilePicture
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="profilepicture")
* @ORM\JoinColumn(name="user_id", referencedColumnName="Id")
*/
protected $user;
/**
* Set user
*
* @param \CashBack\DefaultBundle\Entity\User $user
*
* @return ProfilePicture
*/
public function setUser(\CashBack\DefaultBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* @return \CashBack\DefaultBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
}
用户实体
<?php
namespace CashBack\DefaultBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity
*/
class User
{
/**
* @var string
*
* @ORM\Column(name="FirstName", type="string", length=10, nullable=true)
*/
private $firstname;
/**
* @var string
*
* @ORM\Column(name="LastName", type="string", length=20, nullable=true)
*/
private $lastname;
/**
* @var string
*
* @ORM\Column(name="Gender", type="string", length=1, nullable=true)
*/
private $gender;
/**
* @var string
*
* @ORM\Column(name="Email", type="string", length=50, nullable=false)
*/
private $email;
/**
* @var \DateTime
*
* @ORM\Column(name="DateOfBirth", type="date", nullable=false)
*/
private $dateofbirth;
/**
* @var string
*
* @ORM\Column(name="Username", type="string", length=50, nullable=false)
*/
private $username;
/**
* @var string
*
* @ORM\Column(name="Password", type="string", length=100, nullable=false)
*/
private $password;
/**
* @var integer
*
* @ORM\Column(name="Id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="CashBack\DefaultBundle\Entity\Tag", inversedBy="user")
* @ORM\JoinTable(name="user_tag",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="tag_id", referencedColumnName="Id")
* }
* )
*/
private $tag;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="CashBack\DefaultBundle\Entity\Customrole", inversedBy="user")
* @ORM\JoinTable(name="user_customrole",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="customrole_id", referencedColumnName="Id")
* }
* )
*/
private $customrole;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="CashBack\DefaultBundle\Entity\Shop", inversedBy="user")
* @ORM\JoinTable(name="user_shop",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="shop_id", referencedColumnName="Id")
* }
* )
*/
private $shop;
/**
* Constructor
*/
public function __construct()
{
$this->tag = new \Doctrine\Common\Collections\ArrayCollection();
$this->customrole = new \Doctrine\Common\Collections\ArrayCollection();
$this->shop = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set firstname
*
* @param string $firstname
*
* @return User
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* @return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* @param string $lastname
*
* @return User
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* @return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set gender
*
* @param string $gender
*
* @return User
*/
public function setGender($gender)
{
$this->gender = $gender;
return $this;
}
/**
* Get gender
*
* @return string
*/
public function getGender()
{
return $this->gender;
}
/**
* Set email
*
* @param string $email
*
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set dateofbirth
*
* @param \DateTime $dateofbirth
*
* @return User
*/
public function setDateofbirth($dateofbirth)
{
$this->dateofbirth = $dateofbirth;
return $this;
}
/**
* Get dateofbirth
*
* @return \DateTime
*/
public function getDateofbirth()
{
return $this->dateofbirth;
}
/**
* Set username
*
* @param string $username
*
* @return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* @param string $password
*
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add tag
*
* @param \CashBack\DefaultBundle\Entity\Tag $tag
*
* @return User
*/
public function addTag(\CashBack\DefaultBundle\Entity\Tag $tag)
{
$this->tag[] = $tag;
return $this;
}
/**
* Remove tag
*
* @param \CashBack\DefaultBundle\Entity\Tag $tag
*/
public function removeTag(\CashBack\DefaultBundle\Entity\Tag $tag)
{
$this->tag->removeElement($tag);
}
/**
* Get tag
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getTag()
{
return $this->tag;
}
/**
* Add customrole
*
* @param \CashBack\DefaultBundle\Entity\Customrole $customrole
*
* @return User
*/
public function addCustomrole(\CashBack\DefaultBundle\Entity\Customrole $customrole)
{
$this->customrole[] = $customrole;
return $this;
}
/**
* Remove customrole
*
* @param \CashBack\DefaultBundle\Entity\Customrole $customrole
*/
public function removeCustomrole(\CashBack\DefaultBundle\Entity\Customrole $customrole)
{
$this->customrole->removeElement($customrole);
}
/**
* Get customrole
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCustomrole()
{
return $this->customrole;
}
/**
* Add shop
*
* @param \CashBack\DefaultBundle\Entity\Shop $shop
*
* @return User
*/
public function addShop(\CashBack\DefaultBundle\Entity\Shop $shop)
{
$this->shop[] = $shop;
return $this;
}
/**
* Remove shop
*
* @param \CashBack\DefaultBundle\Entity\Shop $shop
*/
public function removeShop(\CashBack\DefaultBundle\Entity\Shop $shop)
{
$this->shop->removeElement($shop);
}
/**
* Get shop
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getShop()
{
return $this->shop;
}
/** @ORM\OneToOne(targetEntity="ProfilePicture", mappedBy="user", cascade={"persist", "all"}) */
protected $profilepicture;
/**
* Set profilepicture
*
* @param \CashBack\DefaultBundle\Entity\ProfilePicture $profilepicture
*
* @return User
*/
public function setProfilepicture(\CashBack\DefaultBundle\Entity\ProfilePicture $profilepicture)
{
$this->profilepicture = $profilepicture;
$profilepicture->setUser($this);
return $this;
}
/**
* Get profilepicture
*
* @return \CashBack\DefaultBundle\Entity\ProfilePicture
*/
public function getProfilepicture()
{
return $this->profilepicture;
}
}
用户控制器
//adds a new entity from data received via Ajax, no redirect public function addAjaxAction(Request $request) { $user = new User(); $form = $this->createForm(new UserType(), $user); $form->handleRequest($request); $user = $form->getData(); $em = $this->getDoctrine()->getManager(); $em->persist($user); $em->flush(); //prepare the response, e.g. $response = array("code" => 100, "success" => true); //you can return result as JSON , remember to 'use' Response! return new Response(json_encode($response)); }
编辑:检查分析器时,我看到在表单中提交了以下对象: 如果我检查了分析器,我看到以下形式提交的对象:{“username”:“test”,“password”:“test”,“firstname”:“test”,“lastname”:“test”,“电子邮件 “:” 测试”, “性别”: “T”, “出生日期”:{ “月”: “1”, “天”: “1”, “年”: “1902”}, “customrole”: “2”], “ID”: “”, “profilepicture”:{ “ID”: “”}, “_标记”: “YUDiZLi8dY6jtmEhZWk6ivnH3vsQIpnM_fxQ3ClJ2Gw”}
个人资料图片因此为空。