Doctriny - Symfony Flush not adding to DataBase - symfony

The flush function does not add anything to the database even though it doesn't return any error.
Any idea of how can I solve that?
Thanks in advance for your help!
Here is my code:
Controller:
#[Route("/messages")]
public function create(Request $request, ManagerRegistry $signup, UserRepository $userRepository, MessageRepository $messageRepository): Response
{
$message = new Message();
$userRepository = $signup->getRepository(User::class);
$formdico = [];
foreach ($userRepository->findAll() as $user) {
$userform = $this->createForm(MessageType::class, $message);
$formdico[$user->getId()] = $userform;
}
foreach ($formdico as $form) {
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newMessage = new Message();
$newMessage->setSender($userRepository->findOneById($form->getData()->getSender()));
$newMessage->setReceiver($userRepository->findOneById($form->getData()->getSender()));
$newMessage->setContent($form->getData()->getContent());
$newMessage->setCreatedAt(new \DateTime('now'));
$em = $signup->getManager();
$em->persist($newMessage);
$em->flush($newMessage);
}
}
foreach ($userRepository->findAll() as $user) {
$userform = $this->createForm(MessageType::class, $message);
$formdico[$user->getId()] = $userform->createView();
}
return $this->render('message/readAllUser.html.twig', ['users' => $userRepository->findAll(), "formdico" => $formdico, 'messages' => $messageRepository->findAll()]);
}
Entity:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity()]
class Message
{
#[ORM\Id]
#[ORM\GeneratedValue(strategy: "AUTO")]
#[ORM\Column(type: "integer")]
private int $id;
#[ORM\ManyToOne(targetEntity: "App\Entity\User", inversedBy: "sendedMessages")]
private $sender;
#[ORM\ManyToOne(targetEntity: "App\Entity\User", inversedBy: "receivedMessages")]
private $receiver;
#[ORM\Column(type: "text")]
private string $content;
#[ORM\Column(type: "date")]
private \DateTime $createdAt;
/**
* Get the value of id
*/
public function getId()
{
return $this->id;
}
/**
* Set the value of id
*
* #return self
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get the value of sender
*/
public function getSender()
{
return $this->sender;
}
/**
* Set the value of sender
*
* #return self
*/
public function setSender($sender)
{
$this->sender = $sender;
return $this;
}
/**
* Get the value of receiver
*/
public function getReceiver()
{
return $this->receiver;
}
/**
* Set the value of receiver
*
* #return self
*/
public function setReceiver($receiver)
{
$this->receiver = $receiver;
return $this;
}
/**
* Get the value of content
*/
public function getContent()
{
return $this->content;
}
/**
* Set the value of content
*
* #return self
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get the value of createdAt
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set the value of createdAt
*
* #return self
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
}
Form:
<?php
namespace App\Form;
use App\Entity\Message;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
class MessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('sender', IntegerType::class, [])
->add('content', TextType::class, ['label' => false, 'attr' => ['placeholder' => 'Message Content']])
->add('receiver', IntegerType::class, []);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => Message::class,]);
}
}
I tried removing the persist, dumped a lot of things to try understanding the problem but I can't get to solve this...
And the form is valid

Related

Modify POST data before storing in database with Symfony and API-Platform

I'm fairly new to the Symfony universe, so please bear with me if this question has already been answered.
I have provided endpoints with the api-platform to create a RegistrationRequest. A RegistrationRequest has a user that is connected via a ManyToOne relation, so it is stored in another table. In the API, the user or user_id is read-only, this is why the user can not be set in the post data. If a RegistrationRequest is made via the API, the creation fails because the user_id is obviously null.
This is why I would like to set the user manually after a registration request is made via the API but before the RegistrationRequest is stored in the database.
The user is known via the global REMOTE_USER from where I can derive the corresponding user object.
src/Entity/RegistrationRequest.php:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=App\Repository\RegistrationRequestRepository::class)
* #ApiResource(
* normalizationContext={"groups" = {"read"}},
* denormalizationContext={"groups" = {"write"}},
* paginationEnabled=false,
* )
*/
class RegistrationRequest
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"read"})
*/
private $id;
/**
* #ORM\Column(type="string", length=64, nullable=true)
* #Groups({"read", "write"})
*/
private $opt_email;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #Groups({"read", "write"})
*/
private $title;
/**
* #Gedmo\Mapping\Annotation\Timestampable(on="create")
* #ORM\Column(type="datetime")
* #Groups({"read"})
*/
private $created_at;
/**
* #Gedmo\Mapping\Annotation\Timestampable(on="update")
* #ORM\Column(type="datetime")
* #Groups({"read"})
*/
private $updated_at;
/**
* #ORM\Column(type="text", nullable=true)
* #Groups({"read", "write"})
*/
private $notes;
/**
* #ORM\Column(type="string", length=16)
* #Groups({"read", "write"})
*/
private $language_code;
/**
* #ORM\Column(type="text")
* #Groups({"read", "write"})
*/
private $data;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="registrationRequests")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
public function getId(): ?int
{
return $this->id;
}
public function getOptEmail(): ?string
{
return $this->opt_email;
}
public function setOptEmail(?string $opt_email): self
{
$this->opt_email = $opt_email;
return $this;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(?string $title): self
{
$this->title = $title;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updated_at;
}
public function setUpdatedAt(\DateTimeInterface $updated_at): self
{
$this->updated_at = $updated_at;
return $this;
}
public function getNotes(): ?string
{
return $this->notes;
}
public function setNotes(?string $notes): self
{
$this->notes = $notes;
return $this;
}
public function getLanguageCode(): ?string
{
return $this->language_code;
}
public function setLanguageCode(string $language_code): self
{
$this->language_code = $language_code;
return $this;
}
public function getData(): ?string
{
return $this->data;
}
public function setData(string $data): self
{
$this->data = $data;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}
src/Controller/RegistrationRequestController.php:
<?php
namespace App\Controller;
use App\Service\IGSNService;
use App\Entity\RegistrationRequest;
use App\Form\RegistrationRequestType;
use App\Repository\RegistrationRequestRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* #Route("/registration_request")
*/
class RegistrationRequestController extends AbstractController
{
/**
* #Route("/")
*/
public function indexNoLocale(): Response
{
return $this->redirectToRoute('app_registration_request_index', ['_locale' => 'de']);
}
/**
* #Route("/{_locale<%app.supported_locales%>}/", name="app_registration_request_index", methods={"GET"})
*/
public function index(RegistrationRequestRepository $registrationRequestRepository): Response
{
return $this->render('registration_request/index.html.twig', [
'registration_requests' => $registrationRequestRepository->findAll(),
]);
}
/**
* #Route("/{_locale<%app.supported_locales%>}/new", name="app_registration_request_new", methods={"GET", "POST"})
*/
public function new(Request $request, RegistrationRequestRepository $registrationRequestRepository, IGSNService $igsnService, TranslatorInterface $translator): Response
{
$registrationRequest = new RegistrationRequest();
$form = $this->createForm(RegistrationRequestType::class, $registrationRequest);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$json_data = json_decode($registrationRequest->getData());
$err = $igsnService->validate_data($json_data);
if ($json_data !== null && empty($err)) {
$registrationRequestRepository->add($registrationRequest, true);
$this->addFlash(
'success',
$translator->trans('Your changes were saved!')
);
return $this->redirectToRoute('app_registration_request_index', [], Response::HTTP_SEE_OTHER);
} else {
$this->addFlash(
'schema_error',
$err
);
}
}
return $this->renderForm('registration_request/new.html.twig', [
'registration_request' => $registrationRequest,
'form' => $form,
]);
}
/**
* #Route("/{_locale<%app.supported_locales%>}/{id}", name="app_registration_request_show", methods={"GET"})
*/
public function show(RegistrationRequest $registrationRequest): Response
{
return $this->render('registration_request/show.html.twig', [
'registration_request' => $registrationRequest,
]);
}
/**
* #Route("/{_locale<%app.supported_locales%>}/{id}/edit", name="app_registration_request_edit", methods={"GET", "POST"})
*/
public function edit(Request $request, RegistrationRequest $registrationRequest, RegistrationRequestRepository $registrationRequestRepository, IGSNService $igsnService, TranslatorInterface $translator): Response
{
$form = $this->createForm(RegistrationRequestType::class, $registrationRequest);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$json_data = json_decode($registrationRequest->getData());
$err = $igsnService->validate_data($json_data);
if ($json_data !== null && empty($err)) {
$registrationRequestRepository->add($registrationRequest, true);
$this->addFlash(
'success',
$translator->trans('Your changes were saved!')
);
return $this->redirectToRoute('app_registration_request_index', [], Response::HTTP_SEE_OTHER);
} else {
$this->addFlash(
'schema_error',
$err
);
}
}
return $this->renderForm('registration_request/edit.html.twig', [
'registration_request' => $registrationRequest,
'form' => $form,
]);
}
/**
* #Route("/{_locale<%app.supported_locales%>}/{id}", name="app_registration_request_delete", methods={"POST"})
*/
public function delete(Request $request, RegistrationRequest $registrationRequest, RegistrationRequestRepository $registrationRequestRepository, TranslatorInterface $translator): Response
{
if ($this->isCsrfTokenValid('delete' . $registrationRequest->getId(), $request->request->get('_token'))) {
$registrationRequestRepository->remove($registrationRequest, true);
$this->addFlash(
'success',
$translator->trans('Request successfully deleted!')
);
}
return $this->redirectToRoute('app_registration_request_index', [], Response::HTTP_SEE_OTHER);
}
}
config/packages/api_platform.yaml
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
patch_formats:
json: ['application/merge-patch+json']
swagger:
versions: [3]
# Fixes empty api endpoint list with error:
# No operations defined in spec!
# See https://github.com/api-platform/core/issues/4485
metadata_backward_compatibility_layer: false
I have now got it solved with a DataPersister, as suggested by Julien B. in the comments.
namespace App\DataPersister;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Entity\RegistrationRequest;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;
final class RequestDataPersister implements DataPersisterInterface
{
private $security;
public function __construct(Security $security, EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
$this->security = $security;
}
public function supports($data): bool
{
return $data instanceof RegistrationRequest;
}
public function persist($data)
{
$data->setUser($this->security->getUser());
$this->entityManager->persist($data);
$this->entityManager->flush();
return $data;
}
public function remove($data): void
{
// no action needed
}
}

Showing image previews Sonata Admin Bundle Could not load type "file"

I'm trying to show preview image with Sonata Admin Bundle 3 version but I can't do it. I get this error in RecipeAdmin.php: Could not load type "file": class does not exist.
RecipeAdmin.php
<?php
declare(strict_types=1);
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\Form\Type\CollectionType;
use Sonata\AdminBundle\Form\Type\ModelListType;
final class RecipeAdmin extends AbstractAdmin
{
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
$datagridMapper
->add('title',null,['label' =>'Título'])
->add('image',null,['label' =>'Imagen'])
->add('description',null,['label' =>'Descripción'])
->add('score',null,['label' =>'Puntuación'])
->add('visible')
;
}
protected function configureListFields(ListMapper $listMapper): void
{
$listMapper
->add('id')
->add('user', CollectionType::class,['label' =>'Usuario'])
->add('title',null,['label' =>'Título'])
->add('image',null,['label' =>'Imagen'])
->add('description',null,['label' =>'Descripción'])
->add('score',null,['label' =>'Puntuación'])
->add('visible',null,['label' =>'Visible'])
->add('_action', null, [
'label' => 'Acciones',
'actions' => [
'show' => [],
'edit' => [],
'delete' => [],
],
]);
}
protected function configureFormFields(FormMapper $formMapper): void
{
$image = $this->getSubject();
// use $fileFormOptions so we can add other options to the field
$fileFormOptions = ['required' => false];
if ($image && ($webPath = $image->getImage())) {
// get the request so the full path to the image can be set
$request = $this->getRequest();
$fullPath = $request->getBasePath().'/'.$webPath;
// add a 'help' option containing the preview's img tag
$fileFormOptions['help'] = '<img src="'.$fullPath.'" class="admin-preview"/>';
$fileFormOptions['help_html'] = true;
}
$formMapper
->add('title',null,['label' =>'Título'])
->add('image', 'file', $fileFormOptions)
->add('description',null,['label' =>'Descripción'])
->add('score',null,['label' =>'Puntuación'])
->add('visible')
;
}
protected function configureShowFields(ShowMapper $showMapper): void
{
$showMapper
->add('title',null,['label' =>'Título'])
->add('image',null,['label' =>'Imagen'])
->add('description',null,['label' =>'Descripción'])
->add('user', CollectionType::class)
->add('score',null,['label' =>'Puntuaciones'])
->add('visible')
;
}
}
Recipe.php Entity
<?php
namespace App\Entity;
use App\Repository\RecipeRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=RecipeRepository::class)
*/
class Recipe
{
public function __construct() {
$this->categories = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $title;
/**
* #ORM\Column(type="string", length=255)
*/
private $image;
/**
* #ORM\Column(type="string", length=255)
*/
private $description;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="recipes")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $score;
/**
* #ORM\Column(type="boolean")
*/
private $visible;
/**
* #ORM\ManyToMany(targetEntity="Category", inversedBy="recipe", cascade={"persist"})
* #ORM\JoinTable(name="recipes_categories")
*/
private $categories;
public function getId(): ?int
{
return $this->id;
}
public function setId(int $id)
{
$this->id = $id;
return $this;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getImage(): ?string
{
return $this->image;
}
public function setImage(string $image): self
{
$this->image = $image;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getUser()
{
return $this->user;
}
public function setUser($user)
{
$this->user = $user;
return $this;
}
public function getScore(): ?int
{
return $this->score;
}
public function setScore(?int $score): self
{
$this->score = $score;
return $this;
}
public function getVisible(): ?bool
{
return $this->visible;
}
public function setVisible(bool $visible): self
{
$this->visible = $visible;
return $this;
}
public function getCategories()
{
return $this->categories;
}
public function setCategories($categories)
{
$this->categories = $categories;
return $this;
}
public function __toString()
{
return $this->getTitle();
}
public function addCategory(Category $category): self
{
if (!$this->categories->contains($category)) {
$this->categories[] = $category;
}
return $this;
}
public function removeCategory(Category $category): self
{
$this->categories->removeElement($category);
return $this;
}
}
This is the link about how do it: https://symfony.com/doc/current/bundles/SonataAdminBundle/cookbook/recipe_image_previews.html
https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_image_previews.html#showing-image-previews
In the documentation explains that I have to use 'file' type fields but when I use it in my proyect doesn't runs.
This is an error in the doc, instead of file you should use FileType::class and adding :
use Symfony\Component\Form\Extension\Core\Type\FileType;
$formMapper
->add('title',null,['label' =>'Título'])
->add('image', FileType::class, $fileFormOptions)
You will still have error such as :
The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.
In the cookbook they tell you to create an Image Entity so you should add it and follow all the steps :
https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_file_uploads.html
I suggest instead of following this cookbook, you should install and use the sonata media, the integration is easier and it have some nice features such as making different formats for your upload.

Can't create new User

When I try to registering a new user, I had this error
An exception occurred while executing 'INSERT INTO user (username, password, email, gender, newsletter, is_blocked, role_id, purchase_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' with params ["momo", "$2y$13$qCw4ZjU6k4s/dIwTeseEVud/zdjVu3xVper8oHAqsd/fKihq05Ga2", "momo#test.fr", "1", 0, 0, null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'role_id' cannot be null
Thank's in advance.
Here is my User entity:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* * #UniqueEntity(
* fields = {"username"},
* message = "Le nom d'utilisateur existe déjà",
* )
* #UniqueEntity(
* fields = {"email"},
* message = "L'email existe déjà",
* )
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
*/
private $username;
private $roles = [];
/**
* #var string The hashed password
* #ORM\Column(type="string")
*/
private $password;
/**
* #ORM\Column(type="string", length=180, unique=true)
*/
private $email;
/**
* #ORM\Column(type="string", length=255)
*/
private $gender;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
private $newsletter;
/**
* #ORM\Column(type="boolean")
*/
private $isBlocked;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Role", inversedBy="users")
* #ORM\JoinColumn(nullable=false)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Article", inversedBy="users")
*/
private $article;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Firmware", inversedBy="users")
*/
private $firmware;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Purchase", inversedBy="users")
*/
private $purchase;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Note", mappedBy="user",
orphanRemoval=true)
*/
private $notes;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Comment", mappedBy="user",
orphanRemoval=true)
*/
private $comments;
public function __construct()
{
$this->article = new ArrayCollection();
$this->firmware = new ArrayCollection();
$this->notes = new ArrayCollection();
$this->comments = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* A visual identifier that represents this user.
*
* #see UserInterface
*/
public function getUsername(): string
{
return (string) $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
/**
* #see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* #see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* #see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}
/**
* #see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it
here
// $this->plainPassword = null;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getGender(): ?string
{
return $this->gender;
}
public function setGender(string $gender): self
{
$this->gender = $gender;
return $this;
}
public function getNewsletter(): ?bool
{
return $this->newsletter;
}
public function setNewsletter(bool $newsletter): self
{
$this->newsletter = $newsletter;
return $this;
}
public function getIsBlocked(): ?bool
{
return $this->isBlocked;
}
public function setIsBlocked(bool $isBlocked): self
{
$this->isBlocked = $isBlocked;
return $this;
}
public function getRole(): ?Role
{
return $this->role;
}
public function setRole(?Role $role): self
{
$this->role = $role;
return $this;
}
/**
* #return Collection|Article[]
*/
public function getArticle(): Collection
{
return $this->article;
}
public function addArticle(Article $article): self
{
if (!$this->article->contains($article)) {
$this->article[] = $article;
}
return $this;
}
public function removeArticle(Article $article): self
{
if ($this->article->contains($article)) {
$this->article->removeElement($article);
}
return $this;
}
/**
* #return Collection|Firmware[]
*/
public function getFirmware(): Collection
{
return $this->firmware;
}
public function addFirmware(Firmware $firmware): self
{
if (!$this->firmware->contains($firmware)) {
$this->firmware[] = $firmware;
}
return $this;
}
public function removeFirmware(Firmware $firmware): self
{
if ($this->firmware->contains($firmware)) {
$this->firmware->removeElement($firmware);
}
return $this;
}
public function getPurchase(): ?Purchase
{
return $this->purchase;
}
public function setPurchase(?Purchase $purchase): self
{
$this->purchase = $purchase;
return $this;
}
/**
* #return Collection|Note[]
*/
public function getNotes(): Collection
{
return $this->notes;
}
public function addNote(Note $note): self
{
if (!$this->notes->contains($note)) {
$this->notes[] = $note;
$note->setUser($this);
}
return $this;
}
public function removeNote(Note $note): self
{
if ($this->notes->contains($note)) {
$this->notes->removeElement($note);
// set the owning side to null (unless already changed)
if ($note->getUser() === $this) {
$note->setUser(null);
}
}
return $this;
}
/**
* #return Collection|Comment[]
*/
public function getComments(): Collection
{
return $this->comments;
}
public function addComment(Comment $comment): self
{
if (!$this->comments->contains($comment)) {
$this->comments[] = $comment;
$comment->setUser($this);
}
return $this;
}
public function removeComment(Comment $comment): self
{
if ($this->comments->contains($comment)) {
$this->comments->removeElement($comment);
// set the owning side to null (unless already changed)
if ($comment->getUser() === $this) {
$comment->setUser(null);
}
}
return $this;
}
}
Role Entity
<?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\RoleRepository")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=255)
*/
private $description;
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="role")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
/**
* #return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
$user->setRole($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
// set the owning side to null (unless already changed)
if ($user->getRole() === $this) {
$user->setRole(null);
}
}
return $this;
}
public function __toString()
{
return $this->name;
}
}
UserType
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('username', TextType::class, [
'empty_data' => '',
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'empty_data' => '',
'invalid_message' => 'Valeur no correcte',
'options' => ['attr' => ['class' => 'password-field']],
'required' => true,
'first_options' => ['label' => 'Password','empty_data' =>
''],
'second_options' => ['label' => 'Repeat Password','empty_data'
=> ''],
])
->add('email',EmailType::class, [
'empty_data' => '',
])
->add('gender', ChoiceType::class, [
'help' => 'Un choix possible',
'choices' => [
'Femme' => true,
'Homme' => true,
'Autre' => true,
],
])
->add('newsletter')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
SecutityController
<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\UserType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class SecurityController extends AbstractController
{
/**
* #Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' =>
$lastUsername, 'error' => $error]);
}
/**
* #Route("/inscription", name="registration")
*/
public function registration(Request $request, EntityManagerInterface $em,
UserPasswordEncoderInterface $passwordEncoder)
{
$user = new User();
// $role = $user->getRoles();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $passwordEncoder->encodePassword($user, $user-
>getPassword());
$user->setPassword($password);
$user->setIsBlocked(false);
// $user->setRole($role);
$em->persist($user);
$em->flush();
$this->addFlash('success', 'Votre compte à bien été enregistré.');
}
return $this->render('security/registration.html.twig', ['form' =>
$form->createView()]);
}
/**
* #Route("/logout", name="logout")
*/
public function logout() {}
}
On role property Change nullable=false to nullable=true And update the database
* #ORM\JoinColumn(nullable=true)
*/
private $role;

Submiting data in a ManyToMany relation

I have 2 entities, Parking and Agent, each parking can have many Agents and each Agent can administer many parkings.
After I created the relationship, Doctrine automatically added a join table called parking-Agent.
Now I'm trying to populate that table through a form, like when creating a new Agent I can give him one or many parkings, or Vice-Versa. I tried adding a choicetype with multiple choices to the form but it didn't work.
Can you guys help me ?
Entity Agent:
<?php
/**
* #ORM\Entity
* #UniqueEntity(fields="username", message="Username already taken")
*/
class Agent implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
public function getId()
{
return $this->id;
}
/**
* #ORM\Column(type="string", length=191, unique=true)
* #Assert\NotBlank()
*/
private $username;
/**
* #Assert\Length(max=191)
*/
private $plainPassword;
/**
* The below length depends on the "algorithm" you use for encoding
* the password, but this works well with bcrypt.
*
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Parking", mappedBy="agents")
*/
private $parkings;
public function __construct()
{
$this->parkings = new ArrayCollection();
}
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
$this->password = null;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
if (!is_null($password)) {
$this->password = $password;
}
return $this;
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
/**
* #return Collection|Parking[]
*/
public function getParkings(): Collection
{
return $this->parkings;
}
public function addParking(Parking $parking): self
{
if (!$this->parkings->contains($parking)) {
$this->parkings[] = $parking;
$parking->addAgent($this);
return $this;
}
return $this;
}
public function removeParking(Parking $parking): self
{
if ($this->parkings->contains($parking)) {
$this->parkings->removeElement($parking);
$parking->removeAgent($this);
}
return $this;
}
}
Entity Parking:
<?php
/**
* #ORM\Entity(repositoryClass="App\Repository\ParkingRepository")
*/
class Parking
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=55)
*/
private $libelle;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\agent", inversedBy="parkings")
*/
private $agents;
public function __construct()
{
$this->agents = new ArrayCollection();
$this->voitures = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getLibelle(): ?string
{
return $this->libelle;
}
public function setLibelle(string $libelle): self
{
$this->libelle = $libelle;
return $this;
}
/**
* #return Collection|agent[]
*/
public function getAgents(): Collection
{
return $this->agents;
}
public function addAgent(Agent $agent): self
{
if (!$this->agents->contains($agent)) {
$this->agents[] = $agent;
}
return $this;
}
public function removeAgent(Agent $agent): self
{
if ($this->agents->contains($agent)) {
$this->agents->removeElement($agent);
}
return $this;
}
}
My Form:
<?php
namespace App\Form;
ass ParkingType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('libelle');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Parking::class,
]);
}
}
You can try it with a field where you can select multiple elements. The Select2:
->add('personsconcerned', ChoiceType::class, [
'label' => 'form.personsconcerned',
'choices' => $this->groupService->getMailGroups(),
'multiple' => 'multiple',
'mapped' => false,
'choice_translation_domain' => false,
'attr' => [
'data-select' => 'true'
],
'data' => $mailgroups
])
In this example you can see an Element with the posibillity to select more than one thing.
The important thing is the attribute 'multiple', set this to 'multiple' or true.

Symfony2 EntityManager#persist() expects parameter 1 to be an entity object, array given

I am new to Symfony2 and can't to figure out why I'm getting this error. Perhaps there is something wrong with my Entities? So I need some help with it.
An error:
EntityManager#persist() expects parameter 1 to be an entity object, array given.
500 Internal Server Error - ORMInvalidArgumentException
I have the following code:
User.php:
<?php
namespace Acme\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*/
class User
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $username;
/**
* #var string
*/
private $password;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* 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;
}
}
UserRegType.php
<?php
namespace Acme\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Length;
class UserRegType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('username', 'text', array(
'constraints'=>new Length(array('min' => 3))
));
$builder->add('password', 'repeated', array(
'first_name' => 'password',
'second_name' => 'confirm',
'type' => 'password',
'constraints' => new Length(array('min' => 5, 'max' => 8))
));
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'Acme\MainBundle\Entity\User');
}
public function getName() {
return 'user';
}
}
?>
UserController.php:
<?php
namespace Acme\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\MainBundle\Form\Type\UserRegType;
class UserController extends Controller
{
public function registerAction()
{
$form = $this->createForm(new UserRegType());
return $this->render(
'AcmeMainBundle:User:register.html.twig',
array('form' => $form->createView())
);
}
public function createUserAction()
{
$em = $this->getDoctrine()->getEntityManager();
$form = $this->createForm(new UserRegType());
$form->bind($this->getRequest());
$username = $form["username"]->getData();
if ($form->isValid()) {
$reg = $form->getData();
$em->persist($reg);
$em->flush();
$session = $this->get('session');
$session->set('username', $username);
return $this->redirect($this->generateUrl('home'));
}
}
public function loginAction()
{
}
public function logoutAction()
{
}
}

Resources