I got an error like:
Undefined index: id
I know there are few questions like that already present on a Stack Overflow, but the solutions didn't work for me. Could you please review my entities in order of figuring out what exactly is causing this issue?
User
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #ORM\HasLifecycleCallbacks()
* #UniqueEntity("email")
*/
class User
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $user_name;
/**
* #ORM\Column(type="string", length=100)
*/
private $first_name;
/**
* #ORM\Column(type="string", length=100)
*/
private $last_name;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Assert\NotBlank()
* #Assert\Email()
*/
private $email;
/**
* #ORM\Column(type="string", length=20, nullable=true)
*/
private $phone_number;
/**
* #ORM\Column(type="string", length=20, nullable=true)
*/
private $cell_phone_number;
/**
* #ORM\Column(type="boolean")
*/
private $enabled;
/**
* #ORM\Column(type="string", length=100)
* #Assert\NotBlank()
*/
private $timezone;
/**
* #ORM\Column(type="string", length=40)
*/
private $password;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $last_login;
/**
* #var \DateTime $created
*
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var \DateTime $updated
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $updated;
/**
* Many Users have Many Groups.
* #ORM\ManyToMany(targetEntity="Group")
* #ORM\JoinTable(name="user_group",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $group;
/**
* Many Users have Many Roles.
* #ORM\ManyToMany(targetEntity="Role", cascade={"persist"})
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
private $role;
public function __construct() {
$this->enabled = 0;
$this->group = new ArrayCollection();
$this->role = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->user_name;
}
public function setUsername(string $user_name): self
{
$this->user_name = $user_name;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getEnabled(): ?bool
{
return $this->enabled;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function getTimezone(): ?string
{
return $this->timezone;
}
public function setTimezone(string $timezone): self
{
$this->timezone = $timezone;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getLastLogin(): ?\DateTimeInterface
{
return $this->last_login;
}
public function setLastLogin(?\DateTimeInterface $last_login): self
{
$this->last_login = $last_login;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phone_number;
}
public function setPhoneNumber(?string $phone_number): self
{
$this->phone_number = $phone_number;
return $this;
}
/**
* #Assert\IsTrue(message="The password cannot match your first name")
*/
public function isPasswordSafe()
{
return $this->user_name !== $this->password;
}
/**
* #ORM\PrePersist
*/
public function setCreated()
{
$this->created = new \DateTime();
}
public function getCreated()
{
return $this->created;
}
/**
* #ORM\PreUpdate
*/
public function setUpdated()
{
$this->updated = new \DateTime();
}
public function getUpdated()
{
return $this->updated;
}
public function getGroups()
{
return $this->group;
}
public function getRoles()
{
return $this->role;
}
public function addRoles(Role $role)
{
// updating inverse side
$role->addUser($this);
$this->role[] = $role;
}
public function getFirstName(): ?string
{
return $this->first_name;
}
public function setFirstName(string $first_name): self
{
$this->first_name = $first_name;
return $this;
}
public function getLastName(): ?string
{
return $this->last_name;
}
public function setLastName(string $last_name): self
{
$this->last_name = $last_name;
return $this;
}
public function getCellPhoneNumber(): ?string
{
return $this->cell_phone_number;
}
public function setCellPhoneNumber(?string $cell_phone_number): self
{
$this->cell_phone_number = $cell_phone_number;
return $this;
}
}
Group
namespace App\Entity;
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 $group_name;
public function getId(): ?int
{
return $this->id;
}
public function getGroupName(): ?string
{
return $this->group_name;
}
public function setGroupName(string $group_name): self
{
$this->group_name = $group_name;
return $this;
}
}
Role
namespace App\Entity;
use App\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="App\Repository\RoleRepository")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, unique=true)
*/
private $role_name;
/**
* Many Roles have Many Permissions.
* #ORM\ManyToMany(targetEntity="Permission")
* #ORM\JoinTable(name="role_permission",
* joinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
* )
*/
private $permission;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $description;
private $user;
public function __construct() {
$this->user = new ArrayCollection();
$this->permission = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getRolename(): ?string
{
return $this->role_name;
}
public function setRolename(string $role_name): self
{
$this->role_name = $role_name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function addUser(User $user)
{
$this->user[] = $user;
}
}
Controller method
/**
* #Route("/user/{id}", methods={"GET","HEAD"})
* #SWG\Response(
* response=200,
* description="Returns a user or users",
* #SWG\Schema(
* type="array",
* #SWG\Items(ref=#Model(type=User::class, groups={"full"}))
* )
* )
* #SWG\Tag(name="user")
*/
public function get(string $id)
{
$repo = $this->userRepository;
$user = $repo->find($id);
return [
'user' => $user
];
}
Trace
/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(2607):
Doctrine\ORM\Utility\IdentifierFlattener->flattenIdentifier(Object(Doctrine\ORM\Mapping\ClassMetadata),
Array)
/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php(146):
Doctrine\ORM\UnitOfWork->createEntity('App\Entity\User', Array,
Array)
/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php(68):
Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData(Array,
Array)
/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php(152):
Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData()
/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(741):
Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll(Object(Doctrine\DBAL\Driver\PDOStatement),
Object(Doctrine\ORM\Query\ResultSetMapping), Array)
/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(751):
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->load(Array, NULL)
/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(460):
Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadById(Array)
/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php(154):
Doctrine\ORM\EntityManager->find('App\Entity\User', Array, NULL,
NULL) /src/Controller/UserController.php(61):
Doctrine\ORM\EntityRepository->find('1')
/vendor/symfony/http-kernel/HttpKernel.php(149):
App\Controller\UserController->get('1')
/vendor/symfony/http-kernel/HttpKernel.php(66):
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request),
1) /vendor/symfony/http-kernel/Kernel.php(188):
Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request),
1, true) /public/index.php(37):
Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request))
{main}
SOLVED!
The issue was caused by redefined QuoteStrategy::getColumnAlias() method
because "`" was added to query.
The issue was caused by redefined QuoteStrategy::getColumnAlias() method because "`" was added to query.
Related
During a production cache clear I have this message : The type hint of parameter "imageFile" in method "setImageFile" in class "App\Entity\Evenement" is invalid. I follow the instruction of the VichUploaderBundle's documentation on github "basic usage".
Thanks for your help !
below the code of the entity :
<?php
namespace App\Entity;
use App\Repository\EvenementRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\component\HttpFoundation\File\File;
use Symfony\component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity(repositoryClass=EvenementRepository::class)
* #vich\Uploadable
*/
class Evenement
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*
*/
private $titre;
/**
* #ORM\Column(type="string", length=2000, nullable=true)
*/
private $description;
/**
* #ORM\Column(type="string", length=500, nullable=true)
* #Assert\Url()
*/
private $visuel;
/**
* #Vich\UploadableField(mapping="evenement", fileNameProperty="imageName")
* #var File|null
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable=true)
* #var string|null
*/
private $imageName;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTimeInterface|null
*/
private $updatedAt;
/**
* #ORM\Column(type="string", length=500, nullable=true)
*/
private $tarifs;
/**
* #ORM\Column(type="datetime")
*/
private $date;
/**
* #ORM\ManyToMany(targetEntity=Film::class, inversedBy="evenements")
*/
private $films;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $dateFin;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $video;
public function __construct()
{
$this->films = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitre(): ?string
{
return $this->titre;
}
public function setTitre(string $titre): self
{
$this->titre = $titre;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getVisuel(): ?string
{
return $this->visuel;
}
public function setVisuel(?string $visuel): self
{
$this->visuel = $visuel;
return $this;
}
public function getTarifs(): ?string
{
return $this->tarifs;
}
public function setTarifs(?string $tarifs): self
{
$this->tarifs = $tarifs;
return $this;
}
public function getDate(): ?\DateTimeInterface
{
return $this->date;
}
public function setDate(\DateTimeInterface $date): self
{
$this->date = $date;
return $this;
}
/**
* #return Collection|Film[]
*/
public function getFilms(): Collection
{
return $this->films;
}
public function addFilm(Film $film): self
{
if (!$this->films->contains($film)) {
$this->films[] = $film;
}
return $this;
}
public function removeFilm(Film $film): self
{
$this->films->removeElement($film);
return $this;
}
public function getDateFin(): ?\DateTimeInterface
{
return $this->dateFin;
}
public function setDateFin(?\DateTimeInterface $dateFin): self
{
$this->dateFin = $dateFin;
return $this;
}
public function getVideo(): ?string
{
return $this->video;
}
public function setVideo(?string $video): self
{
$this->video = $video;
return $this;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $imageFile
*/
public function setImageFile(?File $imageFile = null): void
{
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageName(?string $imageName): void
{
$this->imageName = $imageName;
}
public function getImageName(): ?string
{
return $this->imageName;
}
}
Please set your fields according to this
Note: Don't forgot to update your database
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Entity\File as EmbeddedFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Assert\File(
* maxSize="51200k",
* mimeTypes = {
* "image/jpeg",
* "image/gif",
* "image/png",
* }
* )
* #Vich\UploadableField(
* mapping="evenement_image",
* fileNameProperty="imageFile.name",
* size="imageFile.size",
* originalName="imageFile.originalName",
* mimeType="imageFile.mimeType"
* )
*
* #var File|null
*/
protected $image;
/**
* #ORM\Embedded(class="Vich\UploaderBundle\Entity\File")
*
* #var EmbeddedFile
*/
protected $imageFile;
public function __construct()
{
$this->imageFile = new EmbeddedFile();
}
public function setImage(?File $image = null): void
{
$this->image = $image;
if (null !== $image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new DateTimeImmutable();
}
}
public function getImage(): ?File
{
return $this->image;
}
public function getImageFile(): ?EmbeddedFile
{
return $this->imageFile;
}
public function setImageFile(EmbeddedFile $imageFile): self
{
$this->imageFile = $imageFile;
return $this;
}
I am new to Symfony and I have a problem with saving a foreign key in the table. I try to explain it as well as possible.
I am making a ToDo application.
- Every user has one profile
- Every profile has many items
- Any User can add new items to the list
- When the user creates a new item, the profile_id should be saved in the Item Table. But I get an Error. I have tried diferent ways to solve that but I can not find a soloution. I hope you can help me with that.
This is my Profile Entity
<?php
namespace App\Entity;
use DateTime;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\ProfileRepository")
*/
class Profile
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $firstName;
/**
* #ORM\Column(type="string", length=255)
*/
private $lastName;
/**
* #ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="profile", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $user;
/**
* #ORM\Column(type="string", length=255)
*/
private $gender;
/**
* #ORM\Column(type="string", length=255)
*/
private $initials;
/**
* #ORM\Column(type="string", length=255)
*/
private $country;
/**
* #ORM\Column(type="string", length=255)
*/
private $city;
/**
* #ORM\Column(type="string", length=255)
*/
private $postalCode;
/**
* #ORM\Column(type="string", length=255)
*/
private $street;
/**
* #ORM\Column(type="string", length=255)
*/
private $houseNumber;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $houseNumberAddition;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $phoneNumber;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $mobileNumber;
/**
* #ORM\Column(type="boolean")
*/
private $accepted;
/**
* #ORM\Column(type="boolean")
*/
private $visible;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Items", mappedBy="profile")
*/
private $items;
public function __construct()
{
$this->items = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(User $user): self
{
$this->user = $user;
return $this;
}
public function getGender(): ?string
{
return $this->gender;
}
public function setGender(string $gender): self
{
$this->gender = $gender;
return $this;
}
public function getInitials(): ?string
{
return $this->initials;
}
public function setInitials(string $initials): self
{
$this->initials = $initials;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getPostalCode(): ?string
{
return $this->postalCode;
}
public function setPostalCode(string $postalCode): self
{
$this->postalCode = $postalCode;
return $this;
}
public function getStreet(): ?string
{
return $this->street;
}
public function setStreet(string $street): self
{
$this->street = $street;
return $this;
}
public function getHouseNumber(): ?string
{
return $this->houseNumber;
}
public function setHouseNumber(string $houseNumber): self
{
$this->houseNumber = $houseNumber;
return $this;
}
public function getHouseNumberAddition(): ?string
{
return $this->houseNumberAddition;
}
public function setHouseNumberAddition(?string $houseNumberAddition): self
{
$this->houseNumberAddition = $houseNumberAddition;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(?string $phoneNumber): self
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function getMobileNumber(): ?string
{
return $this->mobileNumber;
}
public function setMobileNumber(?string $mobileNumber): self
{
$this->mobileNumber = $mobileNumber;
return $this;
}
public function getAccepted(): ?bool
{
return $this->accepted;
}
public function setAccepted(bool $accepted): self
{
$this->accepted = $accepted;
return $this;
}
public function getVisible(): ?bool
{
return $this->visible;
}
public function setVisible(bool $visible): self
{
$this->visible = $visible;
return $this;
}
/**
* #return DateTimeInterface|null
*/
public function getCreatedAt(): ?DateTimeInterface
{
return $this->createdAt;
}
/**
* #param DateTimeInterface $createdAt
* #return $this
*/
public function setCreatedAt(DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return DateTimeInterface|null
*/
public function getUpdatedAt(): ?DateTimeInterface
{
return $this->updatedAt;
}
/**
* #param DateTimeInterface|null $updatedAt
* #return $this
*/
public function setUpdatedAt(?DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist()
*/
public function onPrePersist()
{
$this->createdAt = new DateTime("now");
}
/**
* #ORM\PreUpdate()
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime("now");
}
/**
* #return Collection|Items[]
*/
public function getItems(): Collection
{
return $this->items;
}
public function addItem(Items $item): self
{
if (!$this->items->contains($item)) {
$this->items[] = $item;
$item->setProfile($this);
}
return $this;
}
public function removeItem(Items $item): self
{
if ($this->items->contains($item)) {
$this->items->removeElement($item);
// set the owning side to null (unless already changed)
if ($item->getProfile() === $this) {
$item->setProfile(null);
}
}
return $this;
}
}
This is my Item Entity
<?php
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\ItemsRepository")
* #ORM\HasLifecycleCallbacks
*/
class Items
{
/**
* #var int
*
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Profile", inversedBy="items")
* #ORM\JoinColumn(nullable=false)
*/
private $profile;
/**
* #var string
*
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $title;
/**
* #var string
*
* #ORM\Column(type="text", nullable=false)
*/
private $description;
/**
* #var datetime $createdAt
*
* #ORM\Column(type="datetime", nullable=false)
*/
private $createdAt;
/**
* #var datetime $updatedAt
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
* #return Items
*/
public function setId(int $id): Items
{
$this->id = $id;
return $this;
}
public function getProfile(): ?Profile
{
return $this->profile;
}
public function setProfile(?Profile $profile): self
{
$this->profile = $profile;
return $this;
}
/**
* #return string
*/
public function getTitle(): ?string
{
return $this->title;
}
/**
* #param string $title
* #return Items
*/
public function setTitle(string $title): Items
{
$this->title = $title;
return $this;
}
/**
* #return string
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* #param string $description
* #return Items
*/
public function setDescription(string $description): Items
{
$this->description = $description;
return $this;
}
/**
* #return DateTime
*/
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
/**
* #param DateTime $createdAt
* #return Items
*/
public function setCreatedAt(DateTime $createdAt): Items
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return DateTime
*/
public function getUpdatedAt(): DateTime
{
return $this->updatedAt;
}
/**
* #param DateTime $updatedAt
* #return Items
*/
public function setUpdatedAt(DateTime $updatedAt): Items
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* #ORM\PrePersist()
*/
public function onPrePersist()
{
$this->createdAt = new DateTime("now");
}
/**
* #ORM\PreUpdate()
*/
public function onPreUpdate()
{
$this->updatedAt = new DateTime("now");
}
}
This is my Item Controller where a new Item gets stored
/**
* #Route("/item/create", name="create_item")
* #return Response
*/
public function create()
{
$form = $this->createForm(CreateTodoFormType::class, null, ['action' => $this->generateUrl('store_item')]);
return $this->render('item/create.html.twig', [
'todoForm' => $form->createView(),
]);
}
/**
* #Route("/item/store", name="store_item", methods={"POST"})
* #param EntityManagerInterface $em
* #param Request $request
* #param TranslatorInterface $translator
* #return RedirectResponse
*/
public function store(EntityManagerInterface $em, Request $request, TranslatorInterface $translator)
{
$form = $this->createForm(CreateTodoFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$profile = $em->getRepository(Profile::class)->findBy(['user' => $this->getUser()->getId()]);
$item = new Items();
$item->setTitle($data->getTitle());
$item->setDescription($data->getDescription());
$item->setProfile($profile);
$em->persist($item);
$em->flush();
return $this->redirectToRoute('item');
}
return $this->redirectToRoute('create_item', [
'todoForm' => $form->createView(),
]);
}
When I do it in this way, I get an error!
Argument 1 passed to App\Entity\Items::setProfile() must be an instance of App\Entity\Profile or null, array given, called in C:\xampp\htdocs\projects\SymfonyProjects\symfony_to_do\src\Controller\ItemController.php on line 79
$profile = $em->getRepository(Profile::class)->findBy(['user' => $this->getUser()->getId()]);
This request returns an array, even if it contain just one element. You can use $profile[0] for the first element or better: use the findOneBy method!
I have two entities Template and Zone in Symfony connected by a many to many relationship.
I'm trying to get datas from one of theses so i'm using the following command
$templates = $this->getDoctrine()
->getRepository(Template::class)
->findAll();
I succeed to get my templates datas but the champ "zones" display an empty collection.
Have you got an idea about why I don't get the zones attached to the template.
Here are my code :
<?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\TemplateRepository")
*/
class Template
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* Many Users have Many Groups.
* #ORM\ManyToMany(targetEntity="Zone", inversedBy="templates")
* #ORM\JoinTable(name="templates_zones")
*/
private $zones;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $zonesNumber;
/**
* #ORM\Column(type="string", length=1)
*/
private $format;
/**
* #ORM\Column(type="integer")
*/
private $level;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
private $background;
/**
* Template constructor.
* #param $zones
*/
public function __construct()
{
$this->zones = new \Doctrine\Common\Collections\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 getZonesNumber(): ?int
{
return $this->zonesNumber;
}
public function setZonesNumber(?int $zonesNumber): self
{
$this->zonesNumber = $zonesNumber;
return $this;
}
public function getFormat(): ?string
{
return $this->format;
}
public function setFormat(string $format): self
{
$this->format = $format;
return $this;
}
public function getLevel(): ?int
{
return $this->level;
}
public function setLevel(int $level): self
{
$this->level = $level;
return $this;
}
public function getBackground(): ?string
{
return $this->background;
}
public function setBackground(?string $background): self
{
$this->background = $background;
return $this;
}
/**
* #return Collection|Zone[]
*/
public function getZones(): Collection
{
return $this->zones;
}
public function addZone(Zone $zone): self
{
if (!$this->zones->contains($zone)) {
$this->zones[] = $zone;
}
return $this;
}
public function removeZone(Zone $zone): self
{
if ($this->zones->contains($zone)) {
$this->zones->removeElement($zone);
}
return $this;
}
}
And the zone 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\ZonesRepository")
*/
class Zone
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* Many Groups have Many Users.
* #ORM\ManyToMany(targetEntity="Template", mappedBy="zones")
*/
private $templates;
/**
* Zone constructor.
* #param $templates
*/
public function __construct()
{
$this->templates = new \Doctrine\Common\Collections\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;
}
/**
* #return Collection|Template[]
*/
public function getTemplates(): Collection
{
return $this->templates;
}
public function addTemplate(Template $template): self
{
if (!$this->templates->contains($template)) {
$this->templates[] = $template;
$template->addZone($this);
}
return $this;
}
public function removeTemplate(Template $template): self
{
if ($this->templates->contains($template)) {
$this->templates->removeElement($template);
$template->removeZone($this);
}
return $this;
}
}
This is my entity Fields:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity(repositoryClass="App\Repository\FieldsRepository")
*/
class Fields
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer",unique=true)
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=10, unique=true)
*/
private $unique_id;
/**
* #ORM\ManyToMany(targetEntity="Productgroup")
* #ORM\JoinColumn(name="productgroup", referencedColumnName="id")
*/
private $productgroup;
/**
* #ORM\ManyToOne(targetEntity="Type")
* #ORM\JoinColumn(name="type", referencedColumnName="id")
*/
private $type;
//Getters & Setters
public function getId()
{
return $this->id;
}
public function getUniqueId(): ?string
{
return $this->unique_id;
}
public function setUniqueId(string $unique_id): self
{
$this->unique_id = $unique_id;
return $this;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getType(): ?Type
{
return $this->type;
}
public function setType(?Type $type): self
{
$this->type = $type;
return $this;
}
public function getProductgroup()
{
return $this->productgroup;
}
public function setProductgroup($productgroup): self
{
$this->productgroup = $productgroup;
return $this;
}
public function addProductgroup(Productgroup $productgroup): self
{
$this->productgroup[] = $productgroup;
return $this;
}
public function __construct()
{
$this->productgroup = new ArrayCollection();
}
}
And my entity productgroup:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\ProductgroupRepository")
*/
class Productgroup
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="string", length=10)
*/
private $unique_id;
public function getId(): ?int
{
return $this->id;
}
public function getUniqueId(): ?string
{
return $this->unique_id;
}
public function setUniqueId(string $unique_id): self
{
$this->unique_id = $unique_id;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
The output in my datatable "Fields" is this:
And the output in my datatable "productgroup" is this:
I Like that now in inverse in my productgroup I see also the fields that are connected to the productgroup.
I tried to add an inverseredBy to the row:
/**
* #ORM\ManyToMany(targetEntity="Productgroup", inversedBy="Fields")
* #ORM\JoinColumn(name="productgroup", referencedColumnName="id")
*/
private $productgroup;
But I do not get the result I wish.
You are looking for Many To Many relationship, though Bidirectional
In your case, it should be
/**
* #ManyToMany(targetEntity="Productgroup", inversedBy="fields")
* #JoinTable(name="productgroups_fields")
*/
private $productgroup;
And for Productgroup entity
/**
* Many Groups have Many fields.
* #ManyToMany(targetEntity="Fields", mappedBy="productgroup")
*/
private $fields;
Please, note that inversedBy refers to entity property therefore it should be fields, but not Fields
I serialize some values when I send to DB, now I need to unserialize them in order to iterate over them. In my entity I have this:
public function getValuesText() {
return $this->values_text;
}
and then in the template I show as:
{{ element.getValuesText }}
But I get this raw result:
a:3:{i:1;s:7:"Value 1";i:2;s:7:"Value 2";i:3;s:7:"Value 3";}
And I don't know how to iterate over it to get key, values, what is failing?
UPDATE: Include mapping information
Here is:
<?php
namespace ProductBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ProductBundle\DBAL\Types\StatusType;
use ProductBundle\DBAL\Types\FieldType;
use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* #ORM\Entity
* #ORM\Table(name="product_detail")
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class ProductDetail {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="ProductDetail")
* #ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
/**
* #ORM\Column(type="string", length=255)
*/
protected $description;
/**
* #ORM\Column(type="string", length=255)
*/
protected $label;
/**
* #var string $field_type
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
* #ORM\Column(name="field_type", type="FieldType", nullable=false)
*/
protected $field_type;
/**
* #ORM\Column(name="values_text", type="array")
*/
protected $values_text;
/**
* #ORM\Column(type="string", length=255)
*/
protected $measure_unit;
/**
* #var string $status
* #DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
* #ORM\Column(name="status", type="StatusType", nullable=false)
*/
protected $status;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
protected $created;
/**
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="modified", type="datetime")
*/
protected $modified;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
protected $deletedAt;
/**
* #ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_category", cascade={"persist"})
* #ORM\JoinTable(name="product_detail_has_category",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category", referencedColumnName="id")}
* )
*/
protected $category;
/**
* #ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail", cascade={"persist"})
* #ORM\JoinTable(name="detail_group_has_product_detail",
* joinColumns={#ORM\JoinColumn(name="detail", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="kgroup", referencedColumnName="id")}
* )
*/
protected $detail_group;
/**
* #ORM\Column(name="to_product", type="boolean")
*/
protected $to_product;
public function __construct() {
$this->detail_group = new \Doctrine\Common\Collections\ArrayCollection();
$this->category = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setParent(ProductDetail $parent = null) {
$this->parent = $parent;
}
public function getParent() {
return $this->parent;
}
public function setDescription($description) {
$this->description = $description;
}
public function getDescription() {
return $this->description;
}
public function setLabel($label) {
$this->label = $label;
}
public function getLabel() {
return $this->label;
}
public function setFieldType($field_type) {
$this->field_type = $field_type;
}
public function getFieldType() {
return $this->field_type;
}
public function setValuesText($values_text) {
$this->values_text = $values_text;
}
public function getValuesText() {
return $this->values_text;
}
public function setMeasureUnit($measure_unit) {
$this->measure_unit = $measure_unit;
}
public function getMeasureUnit() {
return $this->measure_unit;
}
public function setStatus($status) {
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
public function setCreated($param) {
$this->created = $param;
return true;
}
public function getCreated() {
return $this->created;
}
public function setModified($param) {
$this->modified = $param;
return true;
}
public function getModified() {
return $this->modified;
}
public function setCategory(\CategoryBundle\Entity\Category $category) {
$this->category[] = $category;
}
public function getCategory() {
return $this->category;
}
public function setDetailGroup(\ProductBundle\Entity\DetailGroup $detailGroup) {
$this->detail_group[] = $detailGroup;
}
public function getDetailGroup() {
return $this->detail_group;
}
public function getDeletedAt() {
return $this->deletedAt;
}
public function setDeletedAt($deletedAt) {
$this->deletedAt = $deletedAt;
}
public function setToProduct($to_product) {
$this->to_product = $to_product;
}
public function getToProduct() {
return $this->to_product;
}
}
Ok, after read and check my code I realize where the problem was:
Doctrine DBAL takes care for serialize/unserialize by using type="array" check here for more info
I made a mistake when I insert values since I was doing a unwanted serialize since as I said before Doctrine take care of this. See below:
Incorrect:
$entity->setValuesText(serialize($form->get('values_text')->getData()));
Correct:
$entity->setValuesText($form->get('values_text')->getData());
That's all, hope is helpful for someone else
Doctrine 2 DBAL ArrayType doesn't check for an array and serialize every type of parameter.
Control your database, that value should be a serialized string starting with s:
Ref: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Types/ArrayType.php