Salut à tous,
Je suis débutant sur symfony ,et j'aime bien ce framework.
J'ai un souci ,j'ai deux entités :
-ModelChaussure
-Photo
J'aimerais ajouter des photo dans un formulaire imbriqué d'ajout nouvelle chaussure basé sur lentité ModeleChaussure.
cependant quand je valide le bouton ajouter chaussure ,la nouvelle chaussure s'ajoute mais pas les photos et ces photos ne sont non plus presentes dans la base de donnéé.
ce qui est curieux est qu'on ne m'affiche pas de message d'erreur.
nous avons ici l'entité ModeleChaussure:



```Entyté ModeleChaussure:
<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use http\Env\Url;

/**
* @ORM\Entity(repositoryClass="App\Repository\ModeleChaussureRepository")
*/
class ModeleChaussure
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=100)
*/
private $nom;

/**
* @ORM\Column(type="decimal", precision=10, scale=2)
*/
private $prix;

/**
* @ORM\OneToMany(targetEntity="App\Entity\Commentaire", mappedBy="modele")
*/
private $commentaires;

/**
* @ORM\ManyToMany(targetEntity="App\Entity\Commande", inversedBy="modeleChaussures")
*/
private $commandes;

/**
* @ORM\ManyToMany(targetEntity="App\Entity\Taille", inversedBy="modeleChaussures")
*/
private $tailles;

/**
* @ORM\OneToMany(targetEntity="App\Entity\Promotion", mappedBy="modeleChaussure")
*/
private $promotions;

/**
* @ORM\ManyToOne(targetEntity="App\Entity\Marque", inversedBy="modeleChaussures")
* @ORM\JoinColumn(nullable=false)
*/
private $marque;

/**
* @ORM\OneToMany(targetEntity="App\Entity\Photo",cascade={"persist"}, mappedBy="modeleChaussure")
*/
private $photo;

/**
* @var photo
*/
private $photos;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $description;

/**
* @ORM\Column(type="string", length=255)
*/
private $coverImage;

public function __construct()
{
$this->commentaires = new ArrayCollection();
$this->commandes = new ArrayCollection();
$this->tailles = new ArrayCollection();
$this->promotions = new ArrayCollection();
$this->photos = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
}

public function getNom(): ?string
{
return $this->nom;
}

public function setNom(string $nom): self
{
$this->nom = $nom;

return $this;
}

public function getPrix(): ?string
{
return $this->prix;
}

public function setPrix(string $prix): self
{
$this->prix = $prix;

return $this;
}

/**
* @return Collection|Commentaire[]
*/
public function getCommentaires(): Collection
{
return $this->commentaires;
}

public function addCommentaire(Commentaire $commentaire): self
{
if (!$this->commentaires->contains($commentaire)) {
$this->commentaires[] = $commentaire;
$commentaire->setModele($this);
}

return $this;
}

public function removeCommentaire(Commentaire $commentaire): self
{
if ($this->commentaires->contains($commentaire)) {
$this->commentaires->removeElement($commentaire);
// set the owning side to null (unless already changed)
if ($commentaire->getModele() === $this) {
$commentaire->setModele(null);
}
}

return $this;
}

/**
* @return Collection|Commande[]
*/
public function getCommandes(): Collection
{
return $this->commandes;
}

public function addCommande(Commande $commande): self
{
if (!$this->commandes->contains($commande)) {
$this->commandes[] = $commande;
}

return $this;
}

public function removeCommande(Commande $commande): self
{
if ($this->commandes->contains($commande)) {
$this->commandes->removeElement($commande);
}

return $this;
}

/**
* @return Collection|Taille[]
*/
public function getTailles(): Collection
{
return $this->tailles;
}

public function addTaille(Taille $taille): self
{
if (!$this->tailles->contains($taille)) {
$this->tailles[] = $taille;
}

return $this;
}

public function removeTaille(Taille $taille): self
{
if ($this->tailles->contains($taille)) {
$this->tailles->removeElement($taille);
}

return $this;
}

/**
* @return Collection|Promotion[]
*/
public function getPromotions(): Collection
{
return $this->promotions;
}

public function addPromotion(Promotion $promotion): self
{
if (!$this->promotions->contains($promotion)) {
$this->promotions[] = $promotion;
$promotion->setModeleChaussure($this);
}

return $this;
}

public function removePromotion(Promotion $promotion): self
{
if ($this->promotions->contains($promotion)) {
$this->promotions->removeElement($promotion);
// set the owning side to null (unless already changed)
if ($promotion->getModeleChaussure() === $this) {
$promotion->setModeleChaussure(null);
}
}

return $this;
}

public function getMarque(): ?Marque
{
return $this->marque;
}

public function setMarque(?Marque $marque): self
{
$this->marque = $marque;

return $this;
}

public function __toString()
{
// TODO: Implement __toString() method.
return $this->nom;
}

/**
* @return Collection|Photo[]
*/
public function getPhotos(): Collection
{
return $this->photos;
}

public function addPhoto(Photo $photo): self
{
if (!$this->photos->contains($photo)) {
$this->photos[] = $photo;
$this->photos->add($photo);
$photo->setModeleChaussure($this);
}

return $this;
}

public function removePhoto(Photo $photo): self
{
if ($this->photos->contains($photo)) {
$this->photos->removeElement($photo);
// set the owning side to null (unless already changed)
if ($photo->getModeleChaussure() === $this) {
$photo->setModeleChaussure(null);
}
}

return $this;
}




public function setPhoto(photo $photo): self
{
$this->$photo;
return $this;
}

public function getPhoto(): ?photo
{
return $this->photo;
}

public function getDescription(): ?string
{
return $this->description;
}

public function setDescription(?string $description): self
{
$this->description = $description;

return $this;
}

public function getCoverImage(): ?string
{
return $this->coverImage;
}

public function setCoverImage(string $coverImage): self
{
$this->coverImage = $coverImage;

return $this;
}
-----------------------------------------------------------
Entité Photo:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;



/**
* @ORM\Entity(repositoryClass="App\Repository\PhotoRepository")
*/
class Photo
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=255)
*/
private $url;

/**
* @ORM\ManyToOne(targetEntity="App\Entity\ModeleChaussure", cascade={"persist"} ,inversedBy="photos")
* @ORM\JoinColumn(nullable=false)
*/
private $modeleChaussure;
private $photo;

public function __construct()
{


$this->modeleChaussure = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
}

public function getUrl(): ?string
{
return $this->url;
}

/**
* @return Collection|ModeleChaussure[]
*/
public function getModeleChaussure(): Collection
{
return $this->modeleChaussure;
}

public function add(ModeleChaussure $modeleChaussure): self
{
if (!$this->modeleChaussure->contains($modeleChaussure)) {
$this->modeleChaussure[] = $modeleChaussure;
$modeleChaussure->setPhoto($this);
}

return $this;
}

public function remove(ModeleChaussure $modeleChaussure): self
{
if ($this->modeleChaussure->contains($modeleChaussure)) {
$this->modeleChaussure->removeElement($modeleChaussure);
// set the owning side to null (unless already changed)
if ($modeleChaussure->getPhoto() === $this) {
$modeleChaussure->setPhoto(null);
}
}

return $this;
}



public function setModeleChaussure(?ModeleChaussure $modeleChaussure): self
{
$this->modeleChaussure = $modeleChaussure;

return $this;
}

public function setUrl(string $url)
{
$this->url;
return $this;
}



}
---------------------------------------------------------------------------------------
ModeleChaussureType:
<?php

namespace App\Form;

use App\Entity\Marque;
use App\Entity\ModeleChaussure;
use App\Entity\Taille;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ModeleChaussureType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom', TextType::class)
->add('prix',MoneyType::class)
->add('description', TextareaType::class)
->add('coverImage',FileType::class,array('label'=>'importez une image de couverture'


))
->add('tailles', EntityType::class, [
'class' => Taille::class,
'choice_label' => 'taille',
'multiple' => true
])
->add('marque',EntityType::class,[
'class'=>Marque::class,
'choice_label'=>'nom'
])

->add(
'photos',
CollectionType::class, [
'entry_type' => PhotoType::class,
'allow_add'=>true,
'entry_options' => ['label' => false],
'prototype' => true,
'by_reference' => false,
])


->add('Ajouter une nouvelle chaussure',SubmitType::class,[
'attr'=>[
'class'=>'btn btn-success'
]
])

;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ModeleChaussure::class,
]);
}
-------------------------------------------------------------------------------------------------
PhotoType:
<?php

namespace App\Form;

use App\Entity\Photo;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PhotoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('url',FileType::class,array('label'=>'ajouter une autre image'))
;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Photo::class,
]);
}
}
------------------------------------------------------------------
controller contenant la fonction pour créer un modele chaussure:

<?php

namespace App\Controller;

use App\Entity\ModeleChaussure;
use App\Form\ModeleChaussureType;
use App\Repository\ClientRepository;
use App\Repository\MarqueRepository;
use App\Repository\ModeleChaussureRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;



class DetailChaussureController extends AbstractController
{
/**
* @var ClientRepository
*/
private $marqueRepository;
private $clientRepository;
function __construct(MarqueRepository $marqueRepository,ClientRepository $clientRepository)
{
$this->marqueRepository = $marqueRepository;
$this->clientRepository=$clientRepository;
}
/**
* @Route("/detail/chaussure/{id}", name="detail_chaussure")
*/
public function index(ModeleChaussureRepository $repository, int $id)
{
$list = $this->marqueRepository->findAll();
$chaussure = $repository->find($id);
return $this->render('detail_chaussure/index.html.twig', [
'chaussure' => $chaussure,'list'=>$list
]);
}

/**
* @Route("/chaussure/new", name="chaussure_nouveau")
* @param Request $request
* @param EntityManagerInterface $manager
* @return \Symfony\Component\HttpFoundation\Response
*/
public function create(Request $request)
{

$chaussure = new ModeleChaussure();
$manager=$this->getDoctrine()->getManager();
$form = $this->createForm(ModeleChaussureType::class, $chaussure);
$form->handleRequest($request);


if($form->isSubmitted() && $form->isValid()) {
$manager=$this->getDoctrine()->getManager();

foreach($chaussure->getPhotos() as $photo)
{
$photo->setModeleChaussure($chaussure);
$manager->persist($photo);

}


$file = $form->get('coverImage')->getData();
$fileName = $this->generateUniqueFileName().'.'.$file->guessExtension();
try{
$file->move(
$this->getParameter('coverImage_directory'),
$fileName
);
}
catch (fileException $e){

}

$manager=$this->getDoctrine()->getManager();

$chaussure->setCoverImage($fileName);
$manager->persist($chaussure);
$manager->flush();

$this->addFlash('success',
"Bravo le modele<strong class='text-danger'>{$chaussure->getNom()}</strong> est bien ajouté");
return $this->redirectToRoute('home');
}
$list = $this->marqueRepository->findAll();

return $this->render('detail_chaussure/nouvelle_chaussure.html.twig', ['form'=>$form->createView(),
'list'=>$list
]);
}

private function generateUniqueFileName()
{

return md5(uniqid());
}
---------------------------------------------------------------------------------------------------
la vue Twig permettant d'afficher le formulaire d'ajout chaussure:

{% extends 'base.html.twig' %}

{% block title %}creation d'une nouvelle chaussure!{% endblock %}

{% form_theme form _self %}

{% block body%}
<div class="container">
<h1>Créer une nouvelle chaussure</h1>
{{ form_start(form) }}
{{ form_row(form.nom, {'label': 'Nom','attr': {'placeholder': 'nom de la chaussure...'}}) }}
{{ form_row(form.prix, {'label': 'Prix','attr': {'placeholder': 'prix de la chaussure...'}}) }}
{{ form_row(form.description, {'label': 'description', 'attr': {'placeholder': 'ajouter une description...'}}) }}

{{ form_row(form.tailles, {'label': 'la taille', 'attr': {'placeholder': 'selectionnez une taille...'}}) }}
{{ form_row(form.marque, {'label': 'Sélectionnez la marque', 'attr': {'placeholder' : 'Votre marque...'}})}}

<div class="form-group">
<button type="button" id="add-photo" class="btn btn-primary">Ajouter une image</button>
</div>

{% block _modeleChaussure_photos_widget %}
<p>Ici,vous pouvez ajouter vos propres photos!</p>



{{ form_widget(form) }}


{{ form_end(form) }}
{% endblock %}

{% endblock %}


{% block _chaussure_entry_widget %}
<div class="form-group" id="block_{{id}}">
<div class="row">
<div class="col-10">
<div class="row">
<div class="col">
{{ form_widget(form.url) }}
</div>

</div>
</div>
<div class="col-2">
<button type="button" class="btn-btn-danger">supprimer</button>
</div>
</div>

</div>
{% endblock %}

{% block javascripts %}

<script>

$('#add-photo').click(function()
{
const index = $('#modele_chaussure_photos div.form-group');
const tmpl= $('#modele_chaussure_photos').data('prototype').replace(/_name_/g, index);

$('#modele_chaussure_photos').append(tmpl);
});
</script>
{% endblock %}



ça fait une semaine que je galère dessus.
s'il vous plait j'ai besoin de votre aide.
Merci d'avance
Modifié par nikky (23 May 2020 - 14:42)