Bonjour la communauté Grafikart
Tout d'abord merci pour votre travail.
Je suis sur symfony 3.1.10 ( Je suis sur symfony depuis 1 mois).
Je rencontre une difficulté avec le formBuilder - j'ai du mal à saisir tout son potentiel.
Je vous présente ma 1ere problématique. Merci pour votre indulgence.
J'ai une relation ManyToMany entre category et advert.
step by step
Voici ma relation sur l'entité advert
/**
* @ORM\ManyToMany(targetEntity="BE\PlateformBundle\Entity\Category", cascade={"persist"})
* @ORM\JoinTable(name="be_advert_category")
*/
private $categories;
Voici mes getters/setters
/**
* Add category
*
* @param Category $category
*/
public function addCategory(Category $category)
{
$this->categories[] = $category;
}
/**
* Remove category
*
* @param Category $category
*/
public function removeCategory(Category $category)
{
$this->categories->removeElement($category);
}
/**
* Get categories
*
* @return ArrayCollection
*/
public function getCategories()
{
return $this->categories;
}
Sachant que je me retrouve avec un ArrayCollection, j'ai ajouté à mon entité User
use Doctrine\Common\Collections\ArrayCollection;
et j'ai affecté l'arrayCollection pour categories comme ceci
public function __construct()
{
$this->date = new \Datetime();
$this->categories = new ArrayCollection();
$this->applications = new ArrayCollection();
}
Si j'ai bien compris ce que je fais -> c'est advert qui est propriétaire de la relation ManyToMany et c'est unidirectionnel. * Si je dis une bétise - prévenez moi, merci
Je n'ai aucun traitement qui définit la relation sur l'entité Category.
Voici mon formBuilder:
<?php
namespace BE\PlateformBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AdvertType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('date', DateType::class, array('widget' => 'single_text'))
->add('title', TextType::class)
->add('content', TextareaType::class)
->add('published', CheckboxType::class)
//->add('author', TextType::class)
->add('image', ImageType::class)
->add('categories', EntityType::class, array(
'class' => 'BEPlateformBundle:Category',
'choice_label' => 'name',
))
->add('save', SubmitType::class)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'BE\PlateformBundle\Entity\Advert'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'be_plateformbundle_advert';
}
}
Voici mon addAction du AdvertController
public function addAction(Request $request)
{
//On récupére l'entity Manager
$em = $this->getDoctrine()->getManager();
$advert = new Advert();
$user = $this->getUser();
//var_dump($user);
//$advert->setAuthor($user);
//var_dump($advert);
$form = $this->createForm(AdvertType::class, $advert);
//var_dump($form);die();
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid())
{
//On persist et flush
$em->persist($advert);
$em->flush();
$request->getSession()->getFlashBag()->add('notice', 'Annonce bien enregistrée.');
// Puis on redirige vers la page de visualisation de cettte annonce
return $this->redirectToRoute('be_plateform_view', array('id' => $advert->getId()));
}
return $this->render('BEPlateformBundle:Advert:add.html.twig', array(
'form' => $form->createView(),
));
}
Mon form s'affiche correctement - il me propose bien la liste des catégories.
Si je submit celui-ci, j'ai ce message d'erreur.
\NoSuchPropertyException: "Could not determine access type for property "categories"."
J'ai du mal à saisir pourquoi -> est ce parceque j'ai un arrayCollection et cela suppose donc que je dois utiliser un type en adéquation avec cet arrayCollection sur mon formBuilder. Si oui/non - je veux bien un eclaircissement et vos remarques, etc..
->comment ecrire la partie du form concernant category.
->add('categories', EntityType::class, array(
'class' => 'BEPlateformBundle:Category',
'choice_label' => 'name',
))
Mon objectif est de bien comprendre "le formbuilder" et le "propertyAccessor".
-> Ma dernière question peut paraitre idiote: -> y'a t'il une correlation ou au contraire une divergence entre propertyAccessor et methode __tostring
Merci pour le temps que vous passerez sur ce post. Merci pour votre indulgence - continuez grafikart c'est génial
Je vous mets mon stackTrace si besoin:
[1] Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException: Could not determine access type for property "categories".
at n/a
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 614
at Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty(array(object(Advert), object(Advert)), 'categories', object(Category))
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 202
at Symfony\Component\PropertyAccess\PropertyAccessor->setValue(object(Advert), object(PropertyPath), object(Category))
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php line 93
at Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator), object(Advert))
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 618
at Symfony\Component\Form\Form->submit(array('date' => '2017-01-30', 'categories' => '1', 'title' => 'test insertion form - FormAdvert', 'content' => 'blabla', 'published' => '1', 'save' => '', '_token' => 'RR1wUrNQ73T2jDVjTjg0MAbsJKuQP3sTSYlPA0yGe1E', 'image' => array('file' => object(UploadedFile))), true)
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler.php line 113
at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest(object(Form), object(Request))
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 488
at Symfony\Component\Form\Form->handleRequest(object(Request))
in C:\wamp\www\labsymf\src\BE\PlateformBundle\Controller\AdvertController.php line 103
at BE\PlateformBundle\Controller\AdvertController->addAction(object(Request))
in line
at call_user_func_array(array(object(AdvertController), 'addAction'), array(object(Request)))
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php line 153
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php line 68
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
in C:\wamp\www\labsymf\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php line 169
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
in C:\wamp\www\labsymf\web\app_dev.php line 30
Après réflexion, mon problème est résolu. - ps: le markdown plante - j'ai pas trouvé pourquoi - je poste comme ça dsl
'class' => 'BEPlateformBundle:Category',
'multiple' => true,
C'est donc bien l'idée d'avoir une collection d'objet qui est envoyée à notre formbuilder qui -> oblige a affecter 'multiple'=> true
C'est totalement logique ;) - comme quoi poser les choses c'est une étape du debug.
Prochaine étape -> affecter le user de la session en cours -> à l'author de l'advert.
-> vérifier mes entités - ma relation
-> regarder la doc pour trouver le bonne méthode. voir si il existe une best practice
-> sachant que je serais amené à faire çà régulièrement -> associer un user à l'author -> voir si cela nécessite un service
Si je rencontre des difficultés - je posterais un nouveau message. :)
Celui-ci peut etre cloturer.