У меня очень странная проблема. У меня есть лицо: Недвижимость
Он имеет подключение ManyToOne к картинкам
Когда я добавляю больше изображений для формы, когда я сохраняю ее, сохраняется только первое добавленное изображение, остальное — нет.
Тем не менее, я могу добавлять новые картинки после каждого сохранения, но только по одной за раз.
Код:
Объект недвижимости
namespace Ciber\PropertyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use \Ciber\UtilBundle\Entity\Traits as CiberTraits;
/**
* Property
*
* @ORM\Table(name="property")
* @ORM\Entity(repositoryClass="Ciber\PropertyBundle\Repository\PropertyRepository")
*/
class Property
{
use ORMBehaviors\Timestampable\Timestampable;
use CiberTraits\AddressTrait;
use CiberTraits\PriceTrait;
use ORMBehaviors\Translatable\Translatable;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;/**
*
* @ORM\OneToMany(targetEntity="Ciber\PropertyBundle\Entity\PropertyImage", mappedBy="property", orphanRemoval=true, cascade={"persist"})
*/
private $propertyImages;
/**
*
* @ORM\OneToMany(targetEntity="Ciber\PropertyBundle\Entity\PropertyPlan", mappedBy="property", orphanRemoval=true, cascade={"persist"})
*/
private $propertyPlans;/**
* @ORM\ManyToOne(targetEntity="Ciber\UserBundle\Entity\User", inversedBy="properties", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;/**
* Constructor
*/
public function __construct()
{
$this->propertyImages = new ArrayCollection();
$this->propertyPlans = new ArrayCollection();
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}/**
* Add PropertyImage
*
* @param \Ciber\PropertyBundle\Entity\PropertyImage $propertyImage
* @return Property
*/
public function addPropertyImage(\Ciber\PropertyBundle\Entity\PropertyImage $propertyImage)
{
//$this->propertyImages[] = $propertyImage;
$this->propertyImages->add($propertyImage);
$propertyImage->setProperty($this);
return $this;
}
/**
* Remove propertyImage
*
* @param \Ciber\PropertyBundle\Entity\PropertyImage $propertyImage
*/
public function removePropertyImage(\Ciber\PropertyBundle\Entity\PropertyImage $propertyImage)
{
$this->propertyImages->removeElement($propertyImage);
}
/**
* Add propertyPlans
*
* @param \Ciber\PropertyBundle\Entity\PropertyPlan $propertyPlans
* @return Property
*/
public function addPropertyPlan(\Ciber\PropertyBundle\Entity\PropertyPlan $propertyPlans)
{
$this->propertyPlans[] = $propertyPlans;
$propertyPlans->setProperty($this);
return $this;
}
/**
* Remove propertyPlans
*
* @param \Ciber\PropertyBundle\Entity\PropertyPlan $propertyPlan
*/
public function removePropertyPlan(\Ciber\PropertyBundle\Entity\PropertyPlan $propertyPlan)
{
$this->propertyPlans->removeElement($propertyPlan);
}
/**
* Get propertyImages
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPropertyImages()
{
return $this->propertyImages;
}/**
* Get propertyPlans
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getPropertyPlans()
{
return $this->propertyPlans;
}
/**
* Gets triggered only on insert
* @ORM\PrePersist
*/
public function onPrePersist()
{
$this->createdAt = new \DateTime("now");
}
public function __call($method, $arguments)
{
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
}
Сущность Picture
namespace Ciber\PropertyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File as File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* PropertyImage
*
* @ORM\Table(name="property_image")
* @ORM\Entity
* @Vich\Uploadable
*/
class PropertyImage
{
use ORMBehaviors\Timestampable\Timestampable;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Ciber\PropertyBundle\Entity\Property", inversedBy="propertyImages")
* @ORM\JoinColumn(name="property_id", referencedColumnName="id")
*/
private $property;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="property_images", fileNameProperty="imageName")
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
private $imageName;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}/**
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return PropertyImage
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @param string $imageName
*
* @return PropertyImage
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set property
*
* @param \AppBundle\Entity\Property $property
*
* @return PropertyImage
*/
public function setProperty( \Ciber\PropertyBundle\Entity\Property $property = null ) {
$this->property = $property;
return $this;
}
/**
* Get property
*
* @return \Ciber\PropertyBundle\Entity\Property
*/
public function getProperty() {
return $this->property;
}
public function __toString()
{
return $this->imageName;
}
}
Форма:
class FlatType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
...
// Pictures
->add('propertyImages', CollectionType::class, array(
'by_reference' => false,
'entry_type' => PropertyImageType::class,
'allow_add' => true,
'allow_delete' => true,
))
->add('propertyPlans', CollectionType::class, array(
'by_reference' => false,
'entry_type' => PropertyPlanType::class,
'allow_add' => true,
'allow_delete' => true,
))
...
;
$builder->add('save', ButtonType::class, array(
'label' => 'property.form.save'
));
}public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ciber\PropertyBundle\Entity\Property',
));
}
}
Интересный факт:
if ($request->isMethod('POST')) {
$form->handleRequest($request);
$property = $form->getData();
dump($property); exit();
...
Когда я выбрасываю $ property — после отправки 2 фотографий одновременно, я получаю следующее:
elements: array:2 [▼
0 => PropertyImage {#3937 ▼
-id: 10
-isDefault: false
-title: null
-property: Property {#2799}
-imageFile: null
-imageName: "5939c65692d47.jpg"#createdAt: DateTime {#3933 ▶}
#updatedAt: DateTime {#2605 ▶}
}
1 => PropertyImage {#4225 ▼
-id: null
-isDefault: false
-title: null
-property: Property {#2799}
-imageFile: UploadedFile {#14 ▶}
-imageName: null
#createdAt: null
#updatedAt: DateTime {#4224 ▶}
}
]
Я действительно понятия не имею, что здесь произошло
(Конечно, у меня есть больше полей, таких как заголовок, который, я думаю, не связан с этой проблемой. Однако, как вы видите, у меня также есть «PropertyPlans ArrayCollection, он выполняет ту же проблему. Только первое сохраняется правильно)
РЕДАКТИРОВАТЬ. Вот мой контроллер:
/**
* @Route("/properties/{property_category}/new", name="propertycreateindex")
*/
public function propertyCreateIndexAction(Request $request)
{
$entity = new Property();
$form = $this->createForm(Ciber\PropertyBundle\Form\FlatType, $entity);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
$property = $form->getData();
$property->setUser($this->getUser());
$property->setIsActive(1);
$em = $this->getDoctrine()->getManager();
$em->persist($property);
$em->flush();
$this->addFlash(
'success',
$this->get('translator')->trans('success.message.create_successfull')
);
return $this->redirectToRoute('dashboard');
}
return $this->render(view.html.twig, array(
'form' => $form->createView(),
'property' => $entity
));
}
И это PropertyImageType.php
namespace Ciber\PropertyBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichImageType;
class PropertyImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('isDefault')
->add('title', TextType::class, array(
'required' => false
))
->add('imageFile', VichImageType::class, array(
'required' => false,
'allow_delete' => true, // not mandatory, default is true
'download_link' => false // default is true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ciber\PropertyBundle\Entity\PropertyImage',
));
}
}
Извините, это моя ошибка. После того, как я проспал несколько часов, я прошел повторное тестирование.
Я нашел, я был неправ. Не первое, но последнее изображение сохранилось.
Отсюда это был простой способ понять, я пропустил одну строчку из учебника.
newinputs.each(function(){
$(this).attr('id', $(this).attr('id').replace(/__name__/g, $randomId));
$(this).attr('name', $(this).attr('name').replace(/__name__/g, $randomId));
});
По умолчанию для свойства CollectionType «property_name» название которую вы должны изменить с помощью javascript после того, как вы создали новый встраиваемый файл из form.prototype
Вы должны изменить название во вновь создаваемых полях.
Других решений пока нет …