How to retrieve associated ManyToOne entity? - symfony

In controller I try to retrieve all order products:
$products = $this->getDoctrine()->getRepository('AppBundle:Ordr')->find(1)->getOrdrProducts();
var_dump($products);
... but $products contain no products.
I try to imitate this.
Entity\Ordr.php :
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="ordr")
* #ORM\Entity
*/
class Ordr
{
public function __construct()
{
$this->ordr_products = new ArrayCollection();
}
/**
* #ORM\Column(name="idOrdr", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idordr;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="OrdrProduct", mappedBy="ordr")
*/
protected $ordr_products;
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getOrdrProducts()
{
return $this->ordr_products;
}
public function getIdordr()
{
return $this->idordr;
}
public function addOrdrProducts(\AppBundle\Entity\OrdrProduct $ordrProducts)
{
$this->ordr_products[] = $ordrProducts;
return $this;
}
public function removeOrdrProducts(\AppBundle\Entity\OrdrProduct $ordrProducts)
{
$this->ordr_products->removeElement($ordrProducts);
}
}
Entity\OrdrProduct.php :
/**
* #ORM\Table(name="ordr_products", indexes={#ORM\Index(name="idOrdr_idx", columns={"idOrdr"})})
* #ORM\Entity
*/
class OrdrProduct
{
/**
* #ORM\Column(name="idOrdrProduct", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idordrproduct;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Ordr", inversedBy="ordr_products")
* #ORM\JoinColumn(name="idOrdr", referencedColumnName="idOrdr")
*/
private $ordr;
public function getIdordrproduct()
{
return $this->idordrproduct;
}
public function setOrdr(\AppBundle\Entity\Ordr $ordr = null)
{
$this->ordr = $ordr;
return $this;
}
public function getOrdr()
{
return $this->ordr;
}
}
My post is mostly code, I apologize for that. I dont know what to add more about the issue.
I can add something more about something else.

Hope this will help you:
Try this to get one order by id (with all order products related to it)
#AppBundle\Repository\OrderRepository.php
public function findOrderById($id)
{
$qb = $this->createQueryBuilder('o')
->join('o.ordr_products', 'r')
->addSelect('r')
->where('o.id = :id')
->setParameter(':id', $id)
;
return $qb->getQuery()
->getOneOrNullResult();
;
}

Related

Inheritance of Symfony Lifecycle Callback annotations

I am on Symfony 4, and I have a problem with Lifecycle callbacks. I have two classes, one model and a child of this model. I would like that every child of the model have the same PrePersist callback but the callback is not triggered. Is it normal or did I do something wrong ?
<?php
// src/Models/QuestionModel.php
namespace App\Models;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ODM\MappedSuperclass
* #ODM\HasLifecycleCallbacks
*/
class QuestionModel
{
/**
* #ODM\Id(strategy="AUTO")
*/
protected $id;
/**
* #ODM\Field(type="date")
*/
protected $createdAt;
/**
* #ODM\PrePersist
*/
public function setCreatedAtValue() {
$this->createdAt = new \DateTime();
}
and the child:
<?php
// src/Document/CDN/Question.php
namespace App\Document\CDN;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use App\Models\QuestionModel;
/**
* #ODM\Document(collection="CDNQuestion")
* #ODM\HasLifecycleCallbacks
*/
class Question extends QuestionModel
{
}
If it is normal that it does not work, do you have a solution for my problem ?
Thx
I would recommend to create separate class for that. Trait should be excellent choice. I have something like that in my projects.
trait TimestampableTrait
{
/**
* #var \DateTime
*
* #ORM\Column(type="datetime", nullable=false)
*/
protected $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime", nullable=true)
*/
protected $updatedAt;
/**
* #ORM\PrePersist
*/
public function updateCreatedAt()
{
$this->createdAt = new \DateTime();
}
/**
* #ORM\PreUpdate
*/
public function preUpdate()
{
$this->updatedAt = new \DateTime();
}
/**
* #return \DateTime|null
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #return string
*/
public function getCreatedAtFormatted()
{
if ($this->createdAt instanceof \DateTime) {
return $this->createdAt->format('d/m/Y h:i:s A');
}
return '';
}
}

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

dql query error class is not defined

Trying to conver my sql queries into dql, seems im doing something wrong.
I need basic joins, something like this.
SELECT a.id, a.title, u.name FROM articles JOIN users ON a.author_id = u.id
Tried
SELECT a.id, a.title, u.name FROM Article a JOIN User u WITH a.author_id = u.id
Getting error
[Semantical Error] line 0, col 34 near 'Article a JOIN': Error: Class 'Article' is not defined.
How should i define? Could you give me please a right solution?
Edit:
Article Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="articles")
*/
class Article
{
/**
* #var integer $id
*
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $title;
/**
* #ORM\Column(type="integer", name="author_id")
*/
protected $authorId;
/**
* #ORM\Column(type="datetime", name="creation_date")
*/
protected $creationDate;
/**
* #ORM\Column(type="string", name="short_content")
*/
protected $shortContent;
/**
* #ORM\Column(type="string")
*/
protected $content;
public function getId()
{
return $this->id;
}
public function getTitle()
{
return $this->title;
}
public function getAuthorId()
{
return $this->authorId;
}
public function getCreationDate()
{
return $this->creationDate;
}
public function getShortContent()
{
return $this->shortContent;
}
public function getContent()
{
return $this->content;
}
}
User Entity
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="bigint")
*/
protected $phone;
/**
* #ORM\Column(type="string")
*/
protected $gender;
/**
* #ORM\Column(type="string")
*/
protected $about;
public function getPhone()
{
return $this->phone;
}
public function getGender()
{
return $this->gender;
}
public function getAbout()
{
return $this->about;
}
}
Refer to the entities in your DQL by their namespaces, i.e. AppBundle:Article and AppBundle:User, that should make the error go away.
Use association mapping (old docs) instead of authorId in your entity, this way Doctrine will take care of loading the author:
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
**/
private $author;
public function getAuthor() {
return $this->author;
}
public function setAuthor($author) {
$this->author = $author;
}
Your query would be reduced to:
SELECT a FROM AppBundle:Article a ORDER BY a.creationDate DESC
Once you have loaded an article, you can conveniently access the author:
...
$author = $article->getAuthor();

No relation between messages and messages_translation

I'm trying to get a multilingual site up with A2lix-i18 & a2lix-form, but I've seem to hit a bump.
I'm able to persist the records, but the translatable_id never gets set.
Any ideas on how this could be occuring?
<?php
//Message.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="messages")
*/
class Message
{
use \A2lix\I18nDoctrineBundle\Doctrine\ORM\Util\Translatable;
/**
* #ORM\Column(type="guid")
* #ORM\Id
* #ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
/**
* #ORM\Column(type="datetime")
*/
protected $created;
/**
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
*/
protected $author;
/**
*/
protected $translations;
public function getTranslations(){
return $this->translations;
}
public function addTranslation($translation){
$this->translations[] = $translation;
}
public function __construct(){
$this->created = new \DateTime();
$this->translations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return guid
*/
public function getId()
{
return $this->id;
}
public function getCreated()
{
return $this->created;
}
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Set author
*
* #param \AppBundle\Entity\User $author
* #return Message
*/
public function setAuthor(\AppBundle\Entity\User $author = null)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return \AppBundle\Entity\User
*/
public function getAuthor()
{
return $this->author;
}
public function setTranslatable($translatable)
{
$this->translatable = $translatable;
}
}
-
//MessageTranslation.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class MessageTranslation implements \A2lix\I18nDoctrineBundle\Doctrine\Interfaces\ManyLocalesInterface
{
use \A2lix\I18nDoctrineBundle\Doctrine\ORM\Util\Translation;
/**
* #ORM\Column(type="text")
*/
protected $message;
/**
* Set message
*
* #param string $message
* #return MessageTranslation
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* #return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function setId($id){
$this->id = $id;
}
/**
* Set locale
*
* #param string $locale
* #return MessageTranslation
*/
public function setLocales($locales)
{
$this->locales = $locales;
return $this;
}
/**
* Get locale
*
* #return string
*/
public function getLocales()
{
return $this->locales;
}
public function setTranslatable($translatable)
{
$this->translatable = $translatable;
}
public function getTranslatable()
{
return $this->translatable;
}
}
I was overriding the default addTranslation and removeTranslation functions. Solved now

How to insert ProyectosHasCentros table in the entities definition?

I have this three tables in my model:
And I need to create the relationship between them in order to get valid entities but I need some help here. This is what I have right now:
Proyectos.php
<?php
namespace PI\ProyectoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="proyectos")
*/
class Proyectos {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=45, unique=true, nullable=false)
*/
protected $nombre;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
protected $estado;
/**
* #ORM\Column(type="string", length=45, nullable=false)
*/
protected $pais;
/**
* #ORM\ManyToOne(targetEntity="PI\ClienteBundle\Entity\Clientes", cascade={"all"})
* #ORM\JoinColumn(name="cliente", referencedColumnName="id")
*/
protected $clientes;
public function getId() {
return $this->id;
}
public function setNombre($nombre) {
$this->nombre = $nombre;
}
public function getNombre() {
return $this->nombre;
}
public function setEstado($estado) {
$this->estado = $estado;
}
public function getEstado() {
return $this->estado;
}
public function setPais($pais) {
$this->pais = $pais;
}
public function getPais() {
return $this->pais;
}
public function setClientes(\PI\ClienteBundle\Entity\Clientes $clientes) {
$this->clientes = $clientes;
}
public function getClientes() {
return $this->clientes;
}
}
And Centros.php
<?php
namespace PI\CentroBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="centros")
*/
class Centros {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="text", unique=true, nullable=false)
*/
protected $descripcion;
/**
* #ORM\ManyToMany(targetEntity="PI\UnidadBundle\Entity\Unidades", inversedBy="centros", cascade={"persist"})
* #ORM\JoinTable(name="unidades_has_centros",
* joinColumns={#ORM\JoinColumn(name="centros_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="unidades_id", referencedColumnName="id")}
* )
*/
protected $unidades;
public function __construct() {
$this->unidades = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setDescripcion($descripcion) {
$this->descripcion = $descripcion;
}
public function getDescripcion() {
return $this->descripcion;
}
public function setUnidades(\PI\UnidadBundle\Entity\Unidades $unidades) {
$this->unidades[] = $unidades;
}
public function getUnidades() {
return $this->unidades;
}
}
How I add the n:m relationship in both sides to get valid entities and to make CRUD operations more easy than create a new Entity ProyectosHasCentros.php and put fields inside it?
If you don't add proyectos_cliente to the second table you can use the ManyToMany relationships in your entities. If you want extra fields, then you have to create an extra entity which contains the relationships with Proyectos and Centros. Beside the relationships you add extra properties, like proyectos_cliente.
Try to use one PK and use UNIQUE for the cliente field

Resources