Symfony, oneToMany relationship Invalid argument supplied for foreach() - symfony

I'm adding oneToMany relationship to database, and its working but when i want to view array i get this error :
Warning: Invalid argument supplied for foreach()
this is my User.php
class User implements AdvancedUserInterface, \Serializable
{
// ...
/**
* #ORM\OneToMany(targetEntity="Acme\CityBundle\Entity\City", mappedBy="user")
**/
private $cities;
public function __construct()
{
$this->cities = new ArrayCollection();
}
/**
* #inheritDoc
*/
public function getCities()
{
$c = array();
foreach ($this->cities as $city) {
$c[] = $city->getCity();
}
return $c;
}
/**
* Add cities
*
* #param \Acme\CityBundle\Entity\City $cities
* #return User
*/
public function addCity(\Acme\CityBundle\Entity\City $city)
{
$city->setUser($this);
$this->cities->add($city);
return $this->cities;
}
and City.php
<?php
namespace Acme\CityBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* City
*/
class City
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="cities")
* #JoinColumn(name="id", referencedColumnName="id")
**/
private $user;
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return City
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getCity()
{
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
Controller
$city=new City();
$em = $this->getDoctrine()->getManager();
$city->setName('Miasto');
$user->addCity($city);
$em->persist($city);
$em->persist($user);
$em->flush();
index controller
public function indexAction()
{
$cities=$this->get('security.context')->getToken()->getUser()->getCities();
return $this->render(
'AcmeUserBundle:User:index.html.twig',array( 'cities'=>$cities));
}
and when i try to show array (cities) in view i get error
Warning: Invalid argument supplied for foreach()
in User.php
foreach ($this->cities as $city)
my table city look (id,name)
Thanks for any help.
EDIT : SOLVED
I have to update my CityBundle\Resources\config\doctrine\City.orm.yml file

In your City class, shouldn't be the relationship something like :
/**
* #ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="cities")
* #JoinColumn(name="cityId", referencedColumnName="id")
**/
private $user;
The join column shouldn't be the id of user's table.
And then, of course:
public function getCities()
{
return $this->cities;
}

Related

Symfony: Persisting in a "ManyToMany with extra data" after implementing bridge entity

I am trying to persist a "collection" of objects that are related between them through an entity that is in a ManyToOne relation with two other entities in order to provide a kind of "ManyToMany" relation but with extrafields.
I have followed the only strategy proposed at symfonycasts and also here in stackoverflow by different users which is to create an entity that will contain as properties the two other entities plus one extra field.
Users make reservations to a travel on a given date, but such reservations offer different options depending on the travel type.
I make part of the reservation process using javascript and ajax, but yet the problem I have is that my controller will only persist the data from the last item from the array.
The controller's lines where I am encountering the trouble are these:
$options = $request->request->get('options') ? $request->request->get('options') : [];
$dateId = $request->request->get('dateId');
$em = $this->getDoctrine()->getManager();
$datesRepository = $em->getRepository(Dates::class);
$date = $datesRepository->find($dateId);
$reservation = new Reservation();
$now = new \DateTime();
$reservation->setDateAjout($now);
$reservation->setStatus('initialized');
$reservation->setDate($date);
/** INTRODUCING OPTIONS */
if(count($options) > 0) {
$reservationOptions = new ReservationOptions();
$optionsRepository = $em->getRepository(Options::class);
foreach ( $options as $key => $value ){
if($value > 0) {
$option = $optionsRepository->find($key);
$reservationOptions->setOptions($option);
$reservationOptions->setAmount($value);
$reservation->addReservationOption($reservationOptions);
//This only persist on the last loop
}
}
}
$em->persist($reservation);
$em->flush();
The entity that relates both entities in a for a "ManyToMany + extra fields" relation:
<?php
namespace App\Entity;
use App\Repository\ReservationOptionsRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=ReservationOptionsRepository::class)
*/
class ReservationOptions
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(
* targetEntity=Reservation::class,
* inversedBy="reservationOptions",
* cascade={"persist"}
* )
* #ORM\JoinColumn(nullable=false)
*/
private $reservation;
/**
* #ORM\ManyToOne(
* targetEntity=Options::class,
* inversedBy="reservationOptions",
* cascade={"persist"}
* )
* #ORM\JoinColumn(nullable=false)
*/
private $options;
/**
* #ORM\Column(type="integer")
*/
private $amount;
public function getId(): ?int
{
return $this->id;
}
public function getReservation(): ?Reservation
{
return $this->reservation;
}
public function setReservation(?Reservation $reservation): self
{
$this->reservation = $reservation;
return $this;
}
public function getOptions(): ?Options
{
return $this->options;
}
public function setOptions(?Options $options): self
{
$this->options = $options;
return $this;
}
public function getAmount(): ?int
{
return $this->amount;
}
public function setAmount(int $amount): self
{
$this->amount = $amount;
return $this;
}
public function __toString()
{
return $this->id;
}
}
The reservation entity looks like this:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\ReservationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ApiResource()
* #ORM\Entity(repositoryClass=ReservationRepository::class)
*/
class Reservation
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity=Dates::class, inversedBy="reservations")
*/
private $date;
/**
* #ORM\ManyToOne(targetEntity=User::class, inversedBy="reservations")
*/
private $user;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $status;
/**
* #ORM\OneToMany(targetEntity=ReservationOptions::class, mappedBy="reservation", orphanRemoval=true, cascade={"persist"})
*/
private $reservationOptions;
public function __construct()
{
$this->travellers = new ArrayCollection();
$this->reservationOptions = new ArrayCollection();
}
public function __toString():string
{
return $this->getStatus();
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(?string $status): self
{
$this->status = $status;
return $this;
}
/**
* #return Collection|ReservationOptions[]
*/
public function getReservationOptions(): Collection
{
return $this->reservationOptions;
}
public function addReservationOption(ReservationOptions $reservationOption): self
{
if (!$this->reservationOptions->contains($reservationOption)) {
$this->reservationOptions[] = $reservationOption;
$reservationOption->setReservation($this);
}
return $this;
}
public function removeReservationOption(ReservationOptions $reservationOption): self
{
if ($this->reservationOptions->removeElement($reservationOption)) {
// set the owning side to null (unless already changed)
if ($reservationOption->getReservation() === $this) {
$reservationOption->setReservation(null);
}
}
return $this;
}
}
The options file looks like this:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Options
*
* #ORM\Table(name="options")
* #ORM\Entity(repositoryClass="App\Repository\OptionsRepository")
*/
class Options
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false, options={"unsigned"=true})
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="prix", type="decimal", precision=10, scale=2, nullable=false)
*/
private $price;
/**
* #ORM\ManyToOne(targetEntity=Travel::class, inversedBy="options")
*/
private $travel;
/**
* #ORM\OneToMany(targetEntity=OptionsTranslations::class, mappedBy="options", orphanRemoval=true, cascade={"persist"})
*/
private $optionsTranslations;
/**
* #ORM\OneToMany(targetEntity=ReservationOptions::class, mappedBy="options", orphanRemoval=true, cascade={"persist"})
*/
private $reservationOptions;
public function __construct()
{
$this->optionsTranslations = new ArrayCollection();
$this->reservationOptions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getPrice(): ?string
{
return $this->price;
}
public function setPrice(string $price): self
{
$this->price = $price;
return $this;
}
public function getTravel(): ?Travel
{
return $this->travel;
}
public function setTravel(?Travel $travel): self
{
$this->travel = $travel;
return $this;
}
/**
* #return Collection|OptionsTranslations[]
*/
public function getOptionsTranslations(): Collection
{
return $this->optionsTranslations;
}
public function addOptionsTranslation(OptionsTranslations $optionsTranslation): self
{
if (!$this->optionsTranslations->contains($optionsTranslation)) {
$this->optionsTranslations[] = $optionsTranslation;
$optionsTranslation->setOptions($this);
}
return $this;
}
public function removeOptionsTranslation(OptionsTranslations $optionsTranslation): self
{
if ($this->optionsTranslations->removeElement($optionsTranslation)) {
// set the owning side to null (unless already changed)
if ($optionsTranslation->getOptions() === $this) {
$optionsTranslation->setOptions(null);
}
}
return $this;
}
public function __toString():string
{
return $this->travel->getMainTitle();
}
/**
* #return Collection|ReservationOptions[]
*/
public function getReservationOptions(): Collection
{
return $this->reservationOptions;
}
public function addReservationOption(ReservationOptions $reservationOption): self
{
if (!$this->reservationOptions->contains($reservationOption)) {
$this->reservationOptions[] = $reservationOption;
$reservationOption->setOptions($this);
}
return $this;
}
public function removeReservationOption(ReservationOptions $reservationOption): self
{
if ($this->reservationOptions->removeElement($reservationOption)) {
// set the owning side to null (unless already changed)
if ($reservationOption->getOptions() === $this) {
$reservationOption->setOptions(null);
}
}
return $this;
}
}
You are reusing the same ReservationOptions entity, changing the option and value on each iteration of the loop. So, you end up with only one ReservationOptions having the values from the last item.
You need to create a new ReservationOptions entity for each option/value.
/** INTRODUCING OPTIONS */
if(count($options) > 0) {
$optionsRepository = $em->getRepository(Options::class);
foreach ( $options as $key => $value ){
if($value > 0) {
$reservationOptions = new ReservationOptions();
$option = $optionsRepository->find($key);
$reservationOptions->setOptions($option);
$reservationOptions->setAmount($value);
$reservation->addReservationOption($reservationOptions);
}
}
}
$em->persist($reservation);
$em->flush();

Symfony join query with One-To-Many relation

I am quite new to symfony as in DQL. I have a problem with query, namely I want to compare the ID's between 'term_id' from table 'TermAssign' with 'id' from table Term and then, the one's who are matching are to be rendered on a template. Relation between Term and TermAssign is OneToMany. There is also a table Offer, which has relation OneToMany with table TermAssign.
This is my Term.php:
<?php
namespace App\OfferBundle\Entity;
use App\OfferBundle\Repository\TermRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=TermRepository::class)
* #ORM\Table(name="term")
*/
class Term
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=true, name="term_description")
*/
private $term_description;
/**
* #ORM\OneToMany(targetEntity=TermAssign::class, mappedBy="term")
*/
private $assign;
public function __construct()
{
$this->assign = new ArrayCollection();
}
function getId(): ?int
{
return $this->id;
}
public function getTermDescription(): ?string
{
return $this->term_description;
}
public function setTermDescription(?string $term_description): self
{
$this->term_description = $term_description;
return $this;
}
/**
* #return Collection|TermAssign[]
*/
public function getAssign(): Collection
{
return $this->assign;
}
public function addAssign(TermAssign $assign): self
{
if (!$this->assign->contains($assign)) {
$this->assign[] = $assign;
$assign->setTerm($this);
}
return $this;
}
public function removeAssign(TermAssign $assign): self
{
if ($this->assign->removeElement($assign)) {
// set the owning side to null (unless already changed)
if ($assign->getTerm() === $this) {
$assign->setTerm(null);
}
}
return $this;
}
}
This is Offer.php:
<?php
namespace App\OfferBundle\Entity;
use App\OfferBundle\Repository\OfferRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints\DateTime;
/**
* #ORM\Entity(repositoryClass=OfferRepository::class)
*/
class Offer
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $title;
/**
* #ORM\Column(type="date", name="offer_date")
*/
private $date;
/**
* #ORM\Column(type="string", unique=true)
*/
private $number;
/**
* #ORM\Column(type="string")
*/
private $description;
/**
* #ORM\OneToMany(targetEntity=TermAssign::class, mappedBy="offer")
*/
private $terms;
public function __construct()
{
$this->terms = new ArrayCollection();
}
/**
* Getting offer's id
*/
public function getId(): ?int
{
return $this->id;
}
/**
* getting offer's Title
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Setting offer's name
*/
public function setTitle($title): self
{
$this->title = $title;
return $this;
}
/**
* getting offer's date
*/
public function getDate(): ?\DateTime
{
return $this->date;
}
/**
* Setting offer's date
*/
public function setDate($date): self
{
$this->date = $date;
return $this;
}
/**
* Offer's number
*/
public function getNumber() : string
{
return $this->number;
}
/**
* Setting offer's number
*/
public function setNumber($number): self
{
$this->number = $number;
return $this;
}
/**
* Offer's description
*/
public function getDescription()
{
return $this->description;
}
/**
* Setting offer's description
*/
public function setDescription($description): void
{
$this->description = $description;
}
/**
* #return Collection|TermAssign[]
*/
public function getTerms(): Collection
{
return $this->terms;
}
public function addTerm(TermAssign $term): self
{
if (!$this->terms->contains($term)) {
$this->terms[] = $term;
$term->setOffer($this);
}
return $this;
}
public function removeTerm(TermAssign $term): self
{
if ($this->terms->removeElement($term)) {
// set the owning side to null (unless already changed)
if ($term->getOffer() === $this) {
$term->setOffer(null);
}
}
return $this;
}
}
And this is TermAssign.php:
<?php
namespace App\OfferBundle\Entity;
use App\OfferBundle\Repository\TermAssignRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass=TermAssignRepository::class)
*/
class TermAssign
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity=Offer::class, inversedBy="terms")
*/
private $offer;
/**
* #ORM\ManyToOne(targetEntity=Term::class, inversedBy="assign")
*/
private $term;
public function getId(): ?int
{
return $this->id;
}
public function getOffer(): ?Offer
{
return $this->offer;
}
public function setOffer(?Offer $offer): self
{
$this->offer = $offer;
return $this;
}
public function getTerm(): ?Term
{
return $this->term;
}
public function setTerm(?Term $term): self
{
$this->term = $term;
return $this;
}
}
I did came up with query of this sort:
/**
* #return Term[] Returns an array of Term objects
*/
public function findByIdField():array
{
$em = $this->getEntityManager();
$query = $em->createQuery("SELECT t, a FROM App\OfferBundle\Entity\Term t JOIN t.term a WHERE a.term_id = t.id");
return $query->getResult();
}
But it's of no use.
Also, this is part of my controller where I invoke query to be passed into the template:
OfferController.php
/**
* #Route("/{id}", name="offer_show", methods={"GET"})
*/
public function show(Offer $offer, int $id): Response
{
$termAssigns = $this->getDoctrine()
->getRepository(TermAssign::class)
->findBy(
['offer'=>$id]
);
$terms = $this->getDoctrine()
->getRepository(Term::class)
->findByIdField();
$conditions = $this->getDoctrine()
->getRepository(Condition::class)
->findAll();
return $this->render('offer/show.html.twig', [
'offer' => $offer,
'terms'=> $terms,
'conditions'=>$conditions,
'termAssigns'=>$termAssigns,
]);
}
The question is, what can I do to achieve something like
SELECT description FROM Term.t where 't.id'='ta.term_id'
'ta' is TermAssign table.
That was WAY much less complicated than I have imagined... I didn't have to create a new query, all I had to do was to import a TermAssign repository to show() function located in OfferController.php and use findBy() function to fetch terms from Term table. Solution below:
OfferController.php:
/**
* #Route("/{id}", name="offer_show", methods={"GET"})
*/
public function show(Offer $offer, int $id, TermAssign $terms): Response
{
**$termAssigns = $this->getDoctrine()
->getRepository(TermAssign::class)
->findBy(
['offer'=>$id]
);
$terms = $this->getDoctrine()
->getRepository(Term::class)
->findBy(
['id'=>$terms->getId()]
);**
$conditions = $this->getDoctrine()
->getRepository(Condition::class)
->findAll();
return $this->render('offer/show.html.twig', [
'offer' => $offer,
'terms'=> $terms,
'conditions'=>$conditions,
'termAssigns'=>$termAssigns,
]);
}

Symfony4 FOSRestBundle try to persist ManyToMany SQL syntax error

I get an SQL syntax error:
An exception occurred while executing 'INSERT INTO group (name) VALUES (?)' with params [\"Entwickler\"]:\n\nSQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'group (name) VALUES ('Entwickler')' at line 1
while I try to persist an entity with a ManyToMany relation.
Scenario
I have an entity called folder and an entity called group. There is a ManyToMany relationship between these entities, because one group can have multiple folders, and one folder can have multiple groups.
There is already one folder with id 1. Now I want to create a group and want to add the folder with id 1 to this group.
Group 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\GroupRepository")
*/
class Group
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Folder", inversedBy="groups")
* #ORM\JoinTable(
* name="group_folder",
* joinColumns={
* #ORM\JoinColumn(name="group_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="folder_id", referencedColumnName="id")
* }
* )
*/
private $folder;
public function __construct()
{
$this->folder = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* #return Collection|Folder[]
*/
public function getFolder(): Collection
{
return $this->folder;
}
public function addFolder(Folder $folder): self
{
if (!$this->folder->contains($folder)) {
$this->folder[] = $folder;
}
return $this;
}
public function removeFolder(Folder $folder): self
{
if ($this->folder->contains($folder)) {
$this->folder->removeElement($folder);
}
return $this;
}
}
Folder Entity
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="App\Repository\FolderRepository")
*/
class Folder
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string", length=45)
* #Assert\NotBlank()
*/
private $name;
/**
* #var Secret[]
* #ORM\OneToMany(targetEntity="App\Entity\Secret", mappedBy="folder")
*/
private $secrets;
/**
* #var Folder[]
*
* #ORM\OneToMany(targetEntity="Folder", mappedBy="parent")
*/
private $children;
/**
* #var Folder
*
* #ORM\ManyToOne(targetEntity="Folder", inversedBy="children")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
private $parent;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Group", mappedBy="folder")
*/
private $groups;
public function __construct()
{
$this->children = new ArrayCollection();
$this->secrets = new ArrayCollection();
$this->groups = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return Secret[]|ArrayCollection
*/
public function getSecrets()
{
return $this->secrets;
}
/**
* #return Folder[]|ArrayCollection
*/
public function getChildren()
{
return $this->children;
}
/**
* #param Folder $children
*/
public function addChildren($children)
{
$this->children[] = $children;
$children->setParent($this);
}
/**
* #return Folder
*/
public function getParent()
{
return $this->parent;
}
/**
* #param Folder $parent
*/
public function setParent($parent)
{
$this->parent = $parent;
}
/**
* #return Collection|Group[]
*/
public function getGroups(): Collection
{
return $this->groups;
}
public function addGroup(Group $group): self
{
if (!$this->groups->contains($group)) {
$this->groups[] = $group;
$group->addFolder($this);
}
return $this;
}
public function removeGroup(Group $group): self
{
if ($this->groups->contains($group)) {
$this->groups->removeElement($group);
$group->removeFolder($this);
}
return $this;
}
}
GroupType Form
<?php
namespace App\Form;
use App\Entity\Folder;
use App\Entity\Group;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class GroupType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('folder', EntityType::class, [
'class' => Folder::class,
'multiple' => true
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Group::class,
]);
}
}
Controller Action which I send the POST Request to
/**
* #param Request $request
* #return View
*
* #Rest\Post("/api/groups", name="api_group_create")
*/
public function CreateGroupAction(Request $request)
{
$group = new Group();
$form = $this->createForm(GroupType::class, $group);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($group);
$em->flush();
return View::create($group, 201);
}
return View::create($form, 400);
}
The request body I send to /api/groups
{
"group": {
"name": "Entwickler",
"folder": [
1
]
}
}
I tried many diffenrent ways to solve that problem, but nothing works as i expected. That drives me nuts for hours now.
Thanks to Mathieu Dormeval, that was the solution.
I altered the group entity definition from:
/**
* #ORM\Entity(repositoryClass="App\Repository\GroupRepository")
*/
class Group
To:
/**
* #ORM\Entity(repositoryClass="App\Repository\GroupRepository")
* #ORM\Table(name="groups")
*/
class Group

Symfony Doctrine return empty values

I use Symfony doctrine to set and get data from my MySQL database. I can push new data without any problem but when I try to get them with a findAll for exemple, I get an array with the good length but nothing in.
Here's my controller:
namespace KGN\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use KGN\CoreBundle\Entity\Appointment;
use KGN\CoreBundle\Entity\Testy;
class AdminController extends Controller
{
public function indexAction()
{
return $this->render('KGNCoreBundle:Admin:index.html.twig');
}
public function aptAction()
{
$rep = $this->getDoctrine()
->getRepository('KGNCoreBundle:Testy');
$testy = $rep->findAll();
// return new Response('This is for show : '. count($testy) );
return new JsonResponse($testy);
}
public function createAction()
{
$em = $this->getDoctrine()->getManager();
$testy = new Testy();
$testy->setTitre('Magnifique');
$testy->setName('Helicoptere');
$em->persist($testy);
$em->flush();
return new Response('This is for create');
}
}
and what I get on my view page
[{},{}]
And it's true that there is 2 elements in my SQL table.
( I have create my entity with php bin/console doctrine:generate:entity without edition stuff in the "Testy" class or rep )
Entity/Testy
namespace KGN\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Testy
*
* #ORM\Table(name="testy")
* #ORM\Entity(repositoryClass="KGN\CoreBundle\Repository\TestyRepository")
*/
class Testy
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set titre
*
* #param string $titre
*
* #return Testy
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set name
*
* #param string $name
*
* #return Testy
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
associed rep
namespace KGN\CoreBundle\Repository;
/**
* TestyRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class TestyRepository extends \Doctrine\ORM\EntityRepository
{
}
Hi The Function findAll Return the correct answer but its return as array of Objects
And JsonResponse can't desplay Object.
to fixe that you have to create a custom function in your repository that return An array exemple
public function getAll() {
$qb = $this->createQueryBuilder('u');
return $qb->getQuery()->getArrayResult();
}
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository("KGNCoreBundle:Testy")->findAll();
Hope its help you

Symfony2 DoctrineBehaviors, JordiLlonchCrudGeneratorBundle, LexikFormFilterBundle issue

I use DoctrineBehaviors to apply translation of my entity, and JordiLlonchCrudGenerator to generate my crud, and LexikFormFilterBundle to generate my form filters type.
My form type
class PageFilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', 'filter_text')
->add('content', 'filter_text')
;
$listener = function(FormEvent $event)
{
// Is data empty?
foreach ($event->getData() as $data) {
if(is_array($data)) {
foreach ($data as $subData) {
if(!empty($subData)) return;
}
}
else {
if(!empty($data)) return;
}
}
$event->getForm()->addError(new FormError('Filter empty'));
};
$builder->addEventListener(FormEvents::POST_BIND, $listener);
}
When i try to filters my entities, the error said hat no field called title in Class Entity\Page.
I understand this problem but i have no idea how to resolve this error, because the field title is into the entity PageTranslation, here my function filters :
protected function filter()
{
$request = $this->getRequest();
$session = $request->getSession();
$filterForm = $this->createForm(new PageFilterType());
$em = $this->getDoctrine()->getManager();
$queryBuilder = $em->getRepository('PageBundle:Page')
->createQueryBuilder('e')
->select('e')
->where('e.deletedAt IS NULL')
;
// Reset filter
if ($request->get('filter_action') == 'reset') {
$session->remove('PageControllerFilter');
}
// Filter action
if ($request->get('filter_action') == 'filter') {
// Bind values from the request
$filterForm->bind($request);
if ($filterForm->isValid()) {
// Build the query from the given form object
$this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($filterForm, $queryBuilder);
// Save filter to session
$filterData = $filterForm->getData();
$session->set('PageControllerFilter', $filterData);
}
} else {
// Get filter from session
if ($session->has('PageControllerFilter')) {
$filterData = $session->get('PageControllerFilter');
$filterForm = $this->createForm(new PageFilterType(), $filterData);
$this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($filterForm, $queryBuilder);
}
}
return array($filterForm, $queryBuilder);
}
I think that i should customize this line but i don't know how
$queryBuilder = $em->getRepository('PageBundle:Page')
->createQueryBuilder('e')
->select('e')
->where('e.deletedAt IS NULL')
;
Any solution for that ?
Also, i have created a trash for each entity, for exemple if one page is deleted the user can find it on trash,
Exemple : http://snapplr.com/snap/xxmk
So i have no problem with the action restore all, but remove all is not functional
This is my action
public function emptyTrashAction(){
$em = $this->getDoctrine()->getEntityManager();
$entities=$em->getRepository('PageBundle:Page')->findByRemoved();
if($entities){
foreach ($entities as $entity) {
$em->remove($entity);
$em->flush();
}
$this->get('session')->getFlashBag()->add('success', 'La corbeille est vide !!');
return $this->redirect($this->generateUrl('pa_trash'));
}else{
$this->get('session')->getFlashBag()->add('error', 'La corbeille est déjà vide !! ');
return $this->redirect($this->generateUrl('pa'));
}
}
What i wanna do, is to delete all entities where the feild DeletedAt is not empty, how can i do this ?
Thanks //
This is my entity Page Class
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Page
* #ORM\Table(name="page")
* #ORM\Entity(repositoryClass="Core\PageBundle\Entity\PageRepository")
*
*/
class Page
{
use ORMBehaviors\Translatable\Translatable;
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\SoftDeletable\SoftDeletable;
use ORMBehaviors\Blameable\Blameable;
public function __call($method, $arguments)
{
return \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor()->getValue($this->translate(), $method);
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="nbview", type="integer", nullable=true)
*/
private $nbview;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nbview
*
* #param integer $nbview
* #return Page
*/
public function setNbview($nbview)
{
$this->nbview = $nbview;
return $this;
}
/**
* Get nbview
*
* #return integer
*/
public function getNbview()
{
return $this->nbview;
}
public function getUpdateLogMessage(array $changeSets = [])
{
return 'Changed: '.print_r($changeSets, true);
}
public function getRemoveLogMessage()
{
return 'removed!';
}
And this is the translation page class
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* #ORM\Table(name="page_lang")
* #ORM\Entity()
*/
class PageTranslation
{
use ORMBehaviors\Translatable\Translation;
use ORMBehaviors\Sluggable\Sluggable;
/**
* #inheritdoc
*/
public function getSluggableFields()
{
return ['title'];
}
/**
* #inheritdoc
*/
public function getSlug()
{
if (!$this->slug) {
$this->generateSlug();
}
return $this->slug;
}
/**
* #var string $title
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string $content
*
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #var string $meta
*
* #ORM\Column(name="meta", type="text", nullable=true)
*/
private $meta;
public function getId(){
return $ths->id;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set title
*
* #param string $title
* #return Page
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Set content
*
* #param string $content
* #return Page
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* #param $method
* #param $args
*
* #return mixed
*/
/**
* Set meta
*
* #param string $meta
* #return PageTranslation
*/
public function setMeta($meta)
{
$this->meta = $meta;
return $this;
}
/**
* Get meta
*
* #return string
*/
public function getMeta()
{
return $this->meta;
}
}

Resources