Insérer les données d'un formulaire dans ma base de données.

Default
,

Bonjour,

Voilà, je suis présentement en train de coder un site en Symfony 4, et je rencontre un soucis.

Ce que je fais

J'ai une entité Advert (annonce), en plus des autres entités qui a pour attribut : id, title, description, price, city, date, author_id et sub_category_id.
Je veux permettre à mes utilisateurs de poster une annonce. J'ai écris le code pour le formulaire, et lorsque je clique sur le bouton afin d'enregistrer mon annonce, j'ai une erreur.

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Cocur\Slugify\Slugify;


/**
 * @ORM\Entity(repositoryClass="App\Repository\AdvertRepository")
 */
class Advert
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Author", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $author = 1;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

    /**
     * @ORM\Column(type="text")
     */
    private $description;

    /**
     * @ORM\Column(type="integer")
     */
    private $price;

    /**
     * @ORM\Column(type="text")
     */
    private $city;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    //private $sold;

    /**
     * @ORM\Column(type="datetime")
     */
    private $date;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\SubCategory", inversedBy="adverts")
     * @ORM\JoinColumn(nullable=false)
     */
    private $subCategory = 222;

    public function __construct()
    {
        $this->date = new \DateTime();
    }

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

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getSlug(): string {
        return (new Slugify())->slugify($this->title);
    }

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

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

        return $this;
    }

    public function getPrice(): ?int
    {
        return $this->price;
    }

    public function setPrice(int $price): self
    {
        $this->price = $price;

        return $this;
    }

    public function getFormattedPrice(): string {
        return number_format($this->price, 0, '', ' ');
    }

    public function getCity(): ?string
    {
        return $this->city;
    }

    public function setCity(string $city): self
    {
        $this->city = $city;

        return $this;
    }

    public function getSold(): ?bool
    {
        return $this->sold;
    }

    public function setSold(bool $sold): self
    {
        $this->sold = $sold;

        return $this;
    }

    public function getDate(): ?\DateTimeInterface
    {
        return $this->date;
    }

    public function setDate(\DateTimeInterface $date): self
    {
        $this->date = $date;

        return $this;
    }


    public function getAuthor()
    {
        return $this->author;
    }


    public function setAuthor($author): self
    {
        $this->author = $author;

        return $this;
    }

    public function getSubCategory()
    {
        return $this->subCategory;
    }

    public function setSubCategory($subCategory)
    {
        $this->subCategory = $subCategory;
    }
}
Le formulaire :
<?php

namespace App\Form;

use App\Entity\Advert;
use App\Entity\Author;
use App\Entity\Category;
use App\Entity\SubCategory;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
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 AdvertType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            /*->add('category', EntityType::class, [
                'class' => Category::class,
                'choice_label' => 'name',
                'multiple' => false
            ])*/
            ->add('title', TextType::class)
            ->add('price', TextType::class)
            ->add('description',TextAreaType::class )
            ->add('city',TextType::class )
            /*->add('author', EntityType::class, [
                'class' => Author::class,
                'choice_label' => 'username',
                'multiple' => false
            ])*/
            /*->add('subCategory', EntityType::class, [
                'class' => SubCategory::class,
                'choice_label' => 'name',
                'multiple' => false
            ])*/
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Advert::class,
        ]);
    }
}

Le controller :

/**
     * @Route("/publier-une-annonce", name="advert.publish")
     * @param Request $request
     * @param ObjectManager $manager
     * @return Response
     */
    public function publishAdvert(Request $request, ObjectManager $manager) {
        $advert = new Advert();

        $formAdvert = $this->createForm(AdvertType::class, $advert);

        $formAdvert->handleRequest($request);
        dump($advert);
        if($formAdvert->isSubmitted() && $formAdvert->isValid()) {

            $manager->persist($advert);
            $manager->flush();


            return $this->redirectToRoute("advert.index");
        }

        return $this->render('advert/publication.html.twig', [
            'formAdvert' => $formAdvert->createView(),
            'current_menu' => 'publication'
        ]);
    }

Ce que je veux

Pour info, je veux enregistrer dans la base de données les infos saisies dans le formulaire et sur le champ author_id, je veux enregistrer l'id de l'utilisateur connecté qui poste l'annonce en question et sur le champ sub_category_id, le nom de la sous-catégorie.

Ce que j'obtiens

L'erreur que j'obtiens est la suivante :

An exception occurred while executing 'INSERT INTO advert (title, description, price, city, date, author_id, sub_category_id) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["Phone", "Galaxy S8", 400, "ORLEANS", "2019-04-20 20:03:37", null, null]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'author_id' cannot be null

4 Réponse

5467
,

Bonsoir,
Tu essaye de persister un Author par défaut:

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Author", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $author = 1;

Plus bas tu as la bonne méthode:

public function __construct()
    {
        $this->date = new \DateTime();
    }
Default
,

Merci pour cette réponse rapide.

Je me suis trompé en fait. J'ai collé le mauvais code. J'avais écrit ceci :

/**
     * @ORM\ManyToOne(targetEntity="App\Entity\Author", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $author;

Et pareil pour l'attribut sold...

Toutefois je suis en train de tester ce que vous avez dit mais j'ai des erreurs...

5467
,

Tu dois envoyer un objet comme relation, Author est un objet pas un integer.

Default
,

Bonsoir pour info pour avoir l'utilisateur qui poste le message la methode this->getUser() est la

Bon

public function publishAdvert(Request $request, ObjectManager $manager) {
    $advert = new Advert();

    $formAdvert = $this->createForm(AdvertType::class, $advert);

    $formAdvert->handleRequest($request);
    dump($advert);
    if($formAdvert->isSubmitted() && $formAdvert->isValid()) {

        $advert->setAuthor($this->getUser());
        $manager->persist($advert);
        $manager->flush();


        return $this->redirectToRoute("advert.index");
    }

    return $this->render('advert/publication.html.twig', [
        'formAdvert' => $formAdvert->createView(),
        'current_menu' => 'publication'
    ]);
}