Symfony 2 doctrine DQL order by two fields - symfony

Hi guys i have two objects Point and Subpoint when i got from the repository with custom DQL The point i want to order the Points by field ord and the Subpoints to field ord.
Here is the Entities:
namespace George\ArchitectureBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Point
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="George\ArchitectureBundle\Entity\PointRepository")
* #Vich\Uploadable
*/
class Point
{
use Translatable;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Object
* #Gedmo\SortableGroup
* #ORM\ManyToOne(targetEntity="George\ObjectsBundle\Entity\Object", inversedBy="architecturespoints")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
private $object;
/**
* #ORM\OneToMany(targetEntity="George\ArchitectureBundle\Entity\Subpoint", mappedBy="point")
*/
private $subpoints;
/**
* #var integer
* #Gedmo\SortablePosition
* #ORM\Column(name="ord", type="integer")
*/
private $ord;
/**
* #var \DateTime
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated", type="datetime")
*/
private $updated;
/**
* #var \DateTime
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
private $created;
public function __construct()
{
$this->subpoints = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #return Object
*/
public function getObject()
{
return $this->object;
}
/**
* #param Object $object
*/
public function setObject($object)
{
$this->object = $object;
}
/**
* #return int
*/
public function getOrd()
{
return $this->ord;
}
/**
* #param int $ord
*/
public function setOrd($ord)
{
$this->ord = $ord;
}
/**
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* #return mixed
*/
public function getSubpoints()
{
return $this->subpoints;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="point_image", fileNameProperty="imageName")
*
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*
* #var string
*/
private $imageName;
/**
* 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 $image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($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->setModefied(new \DateTime('now')) ;
}
}
/**
* #return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
}
Subpoint:
namespace George\ArchitectureBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Knp\DoctrineBehaviors\Model\Translatable\Translatable;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Subpoint
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="George\ArchitectureBundle\Entity\SubpointRepository")
* #Vich\Uploadable
*/
class Subpoint
{
use Translatable;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Points
* #Gedmo\SortableGroup
* #ORM\ManyToOne(targetEntity="George\ArchitectureBundle\Entity\Point", inversedBy="subpoints")
*/
private $point;
/**
* #var integer
* #Gedmo\SortablePosition
* #ORM\Column(name="ord", type="integer")
*/
private $ord;
/**
* #var \DateTime
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated", type="datetime")
*/
private $updated;
/**
* #var \DateTime
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created", type="datetime")
*/
private $created;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #return Points
*/
public function getPoint()
{
return $this->point;
}
/**
* #param Points $point
*/
public function setPoint($point)
{
$this->point = $point;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="point_image", fileNameProperty="imageName")
*
* #var File
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*
* #var string
*/
private $imageName;
/**
* 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 $image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($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->setModefied(new \DateTime('now')) ;
}
}
/**
* #return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #param string $imageName
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
}
/**
* #return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* #return int
*/
public function getOrd()
{
return $this->ord;
}
/**
* #param int $ord
*/
public function setOrd($ord)
{
$this->ord = $ord;
}
}
Repository Point and here i want when i got the Point to be oredered by ord and the subpoints to be ordered by ord:
namespace George\ArchitectureBundle\Entity;
/**
* PointRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class PointRepository extends \Doctrine\ORM\EntityRepository
{
public function getPointsByObject($object)
{
$em = $this->getEntityManager();
$query = $em->createQuery("SELECT p FROM George\ArchitectureBundle\Entity\Point p WHERE p.object =".$object." ORDER BY p.ord ASC");
return $query->getResult();
}
}
But when i put in the creatQuery in Point repository
"SELECT p FROM George\ArchitectureBundle\Entity\Point p WHERE p.object =".$object." ORDER BY p.ord ASC, p.subpoints.ord ASC "
I got error:
[Semantical Error] line 0, col 107 near 'ord ASC ': Error: Class George\ArchitectureBundle\Entity\Point has no field or association named subpoints.ord
EDIT
The solution to the problem is this with query builder with guidance of #Yoshi and #Veve:
public function getPointsByObject($object)
{
$em = $this->getEntityManager();
// $query = $em->createQuery("SELECT p FROM George\ArchitectureBundle\Entity\Point p left join George\ArchitectureBundle\Entity\Subpoint s WITH s.point = p WHERE p.object =".$object." ORDER BY p.ord ASC, s.ord ASC");
$qb = $em->createQueryBuilder();
$qb->select('p')
->from('George\ArchitectureBundle\Entity\Point','p')
->where(' p.object =:object')
->leftJoin('George\ArchitectureBundle\Entity\Subpoint', 's', 'WITH', 's.point = p')
->orderBy('p.ord','ASC')
->orderBy('s.ord','ASC');
$qb->setParameters(array(
'object' => $object
));
$query= $qb->getQuery();
return $query->getResult();
}

You have to join the subpoint to order by one of its attributes:
"SELECT p FROM George\ArchitectureBundle\Entity\Point p
JOIN George\ArchitectureBundle\Entity\Subpoint s WITH s.point = p.id
WHERE p.object =".$object."
ORDER BY p.ord ASC, s.ord ASC"
And as Yoshi commented, you should use the queryBuilder and add your parameters with it instead of building your query by hand.

Related

Doctrine. One to many. How to write annotations?

I have a OneToMany relation between two tables 'user' and 'profil'
(a user has one only profile, and a profile can be asseigned to many users)
I'm getting this error whenever I try to update the schema in doctrine console.
here is my two entities :
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping\ManyToOne;
/**
* user
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class user
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
public function __construct()
{
}
/**
* #var boolean
*
* #ORM\Column(name="etat", type="boolean")
*/
private $etat;
/**
* #var profil $profil
*
* #ORMManyToOne(targetEntity="profil", inversedBy="users", cascade={"persist", "merge"})
* #ORMJoinColumns({
* #ORMJoinColumn(name="profil", referencedColumnName="id")
* })
*/
private $profil;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id
*
* #param integer $id
* #return user
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* 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;
}
/**
* Set etat
*
* #param boolean $etat
* #return user
*/
public function setEtat($etat)
{
$this->etat = $etat;
return $this;
}
/**
* Get etat
*
* #return boolean
*/
public function getEtat()
{
return $this->etat;
}
/**
* Get profil
*
* #return integer
*/
public function getProfil()
{
return $this->profil;
}
/**
* Set profil
*
* #param integer $profil
* #return user
*/
public function setProfil($profil)
{
$this->profil = $profil;
return $this;
}
public function getUsername()
{
return $this->id;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
return $user->getId() == $this->getId();
}
}
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\OneToMany;
/**
* profil
*
* #ORM\Table(name="profil")
* #ORM\Entity
*/
class profil
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="libelle", type="string", length=20)
*/
private $libelle;
/**
* #var ArrayCollection $users
*
* #ORMOneToMany(targetEntity="user", mappedBy="profil", cascade={"persist", "remove", "merge"})
*/
private $users;
public function __construct()
{
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set libelle
*
* #param string $libelle
* #return profil
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
return $this;
}
/**
* Get libelle
*
* #return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
* Set id
*
* #param integer $id
* #return profil
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
public function __toString() {
return $this->libelle;
}
}
You have syntax mistake.
#ORMManyToOne - this is mistake.
#ORM\ManyToOne(targetEntity="Profil", inversedBy="users")
Above will be correct. And everywhere you use ORM You need to write ORM\something. ORM - is just a namespace, or simply path to the ORM classes in doctrine vendor directory!
Every class name should start with capital letter. It is a wright way! So you should write class User, but not class user!
You didn't show in Profil class, that you have a lot of users to each profil. the users field will be of array collection type (simple array but with useful methods.) So in Profil class in __construct() method:
public function __construct()
{
$this->users = new ArrayCollection();
}
You have One-To-Many, Bidirectional relation.
You can say :
Every (ONE) profile can have a lot of (MANY) users, which use it (One-To-Many)
Every user can use only one exact profile
So try this
// Class Profil
/**
* Bidirectional - One-To-Many (INVERSED SIDE)
* One Profile can have many users, which use it
*
* #var ArrayCollection $users
*
* #ORM\OneToMany(targetEntity="Path-to-your-user-class\Users", mappedBy="profil", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
// Class user
/**
* Bidirectional - One-To-Many (OWNER SIDE)
* One user have only one profile (or profil)
*
* #var Profil $profil
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Profil", inversedBy="users")
* #ORM\JoinColumn(name="profil_id", referencedColumnName="id")
*/
private $profil;

Symfony Insert Foreign Key Value

I have 3 tables: EdiTradingPartner, EdiDocType and EdiTradingPartnerTransactions
src\Matrix\MatrixEdiBundle\Entity\EdiTradingPartner
namespace Matrix\MatrixEdiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* EdiTradingPartner
*
* #ORM\Table(name="edi_trading_partner")
* #ORM\Entity(repositoryClass="Matrix\MatrixEdiBundle\Repository\EdiTradingPartnerRepository")
*/
class EdiTradingPartner
{
/**
* #var string
*
* #ORM\Column(name="edi_interchange_id", type="string", length=30, nullable=false)
*/
private $ediInterchangeId;
/**
* #var string
*
* #ORM\Column(name="tp_name", type="string", length=30, nullable=false)
*/
private $tpName;
/**
* #var string
*
* #ORM\Column(name="tp_location", type="string", length=50, nullable=false)
*/
private $tpLocation;
/**
* #var integer
*
* #ORM\Column(name="edi_trading_partner_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $ediTradingPartnerId;
/**
* Set ediInterchangeId
*
* #param string $ediInterchangeId
* #return EdiTradingPartner
*/
public function setEdiInterchangeId($ediInterchangeId)
{
$this->ediInterchangeId = $ediInterchangeId;
return $this;
}
/**
* Get ediInterchangeId
*
* #return string
*/
public function getEdiInterchangeId()
{
return $this->ediInterchangeId;
}
/**
* Set tpName
*
* #param string $tpName
* #return EdiTradingPartner
*/
public function setTpName($tpName)
{
$this->tpName = $tpName;
return $this;
}
/**
* Get tpName
*
* #return string
*/
public function getTpName()
{
return $this->tpName;
}
/**
* Set tpLocation
*
* #param string $tpLocation
* #return EdiTradingPartner
*/
public function setTpLocation($tpLocation)
{
$this->tpLocation = $tpLocation;
return $this;
}
/**
* Get tpLocation
*
* #return string
*/
public function getTpLocation()
{
return $this->tpLocation;
}
/**
* Get ediTradingPartnerId
*
* #return integer
*/
public function getEdiTradingPartnerId()
{
return $this->ediTradingPartnerId;
}
}
src\Matrix\MatrixEdiBundle\Entity\EdiDocType
<?php
namespace Matrix\MatrixEdiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* EdiDocType
*
* #ORM\Table(name="edi_doc_type")
* #ORM\Entity(repositoryClass="Matrix\MatrixEdiBundle\Repository\EdiDocTypeRepository")
*/
class EdiDocType
{
/**
* #var integer
*
* #ORM\Column(name="doc_type", type="integer", nullable=false)
*/
private $docType;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="direction", type="string", length=10, nullable=false)
*/
private $direction;
/**
* #var integer
*
* #ORM\Column(name="edi_doc_type_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $ediDocTypeId;
/**
* Set docType
*
* #param integer $docType
* #return EdiDocType
*/
public function setDocType($docType)
{
$this->docType = $docType;
return $this;
}
/**
* Get docType
*
* #return integer
*/
public function getDocType()
{
return $this->docType;
}
/**
* Set name
*
* #param string $name
* #return EdiDocType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return EdiDocType
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set direction
*
* #param string $direction
* #return EdiDocType
*/
public function setDirection($direction)
{
$this->direction = $direction;
return $this;
}
/**
* Get direction
*
* #return string
*/
public function getDirection()
{
return $this->direction;
}
/**
* Get ediDocTypeId
*
* #return integer
*/
public function getEdiDocTypeId()
{
return $this->ediDocTypeId;
}
}
src\Matrix\MatrixEdiBundle\Entity\EdiTradingPartnerTransactions
namespace Matrix\MatrixEdiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* EdiTradingPartnerTransactions
*
* #ORM\Table(name="edi_trading_partner_transactions", indexes={#ORM\Index(name="edi_tp_id", columns={"edi_tp_id", "edi_doc_type_id"}), #ORM\Index(name="edi_transactions_id", columns={"edi_doc_type_id"}), #ORM\Index(name="IDX_F2BE50F7B9C737A1", columns={"edi_tp_id"})})
* #ORM\Entity(repositoryClass="Matrix\MatrixEdiBundle\Repository\EdiTradingPartnerTransactionsRepository")
*/
class EdiTradingPartnerTransactions
{
/**
* #var integer
*
* #ORM\Column(name="edi_tp_transactions_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $ediTpTransactionsId;
/**
* #var \Matrix\MatrixEdiBundle\Entity\EdiDocType
*
* #ORM\ManyToOne(targetEntity="Matrix\MatrixEdiBundle\Entity\EdiDocType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="edi_doc_type_id", referencedColumnName="edi_doc_type_id")
* })
*/
private $ediDocType;
/**
* #var \Matrix\MatrixEdiBundle\Entity\EdiTradingPartner
*
* #ORM\ManyToOne(targetEntity="Matrix\MatrixEdiBundle\Entity\EdiTradingPartner")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="edi_tp_id", referencedColumnName="edi_trading_partner_id")
* })
*/
private $ediTp;
/**
* Get ediTpTransactionsId
*
* #return integer
*/
public function getEdiTpTransactionsId()
{
return $this->ediTpTransactionsId;
}
/**
* Set ediDocType
*
* #param \Matrix\MatrixEdiBundle\Entity\EdiDocType $ediDocType
* #return EdiTradingPartnerTransactions
*/
public function setEdiDocType(\Matrix\MatrixEdiBundle\Entity\EdiDocType $ediDocType = null)
{
$this->ediDocType = $ediDocType;
return $this;
}
/**
* Get ediDocType
*
* #return \Matrix\MatrixEdiBundle\Entity\EdiDocType
*/
public function getEdiDocType()
{
return $this->ediDocType;
}
/**
* Set ediTp
*
* #param \Matrix\MatrixEdiBundle\Entity\EdiTradingPartner $ediTp
* #return EdiTradingPartnerTransactions
*/
public function setEdiTp(\Matrix\MatrixEdiBundle\Entity\EdiTradingPartner $ediTp = null)
{
$this->ediTp = $ediTp;
return $this;
}
/**
* Get ediTp
*
* #return \Matrix\MatrixEdiBundle\Entity\EdiTradingPartner
*/
public function getEdiTp()
{
return $this->ediTp;
}
}
I want to insert into EdiTradingPartnerTransactions table yet I really don't know what to do since I've been receiving this error:
Catchable fatal error: Argument 1 passed to
Matrix\MatrixEdiBundle\Entity\EdiTradingPartnerTransactions::setEdiTp()
must be an instance of
Matrix\MatrixEdiBundle\Entity\EdiTradingPartner, string given, called
in
C:\xampp\htdocs\Editracker\src\Matrix\MatrixEdiBundle\Controller\MatrixController.php
on line 474 and defined in
C:\xampp\htdocs\Editracker\src\Matrix\MatrixEdiBundle\Entity\EdiTradingPartnerTransactions.php
on line 85
Here's my function in the controller side:
public function deleteTpTransAction($tpId, $docType, $direction, $tpName) {
$em = $this->getDoctrine()->getManager();
$docTypeId = $em->getRepository('MatrixEdiBundle:EdiDocType')->getId($docType, $direction);
if ($docTypeId != null) {
$result = $em->getRepository('MatrixEdiBundle:EdiTradingPartnerTransactions')->getTpTrans($tpId, $docType, $direction);
if ($result == null) {
$transaction = new EdiTradingPartnerTransactions();
$transaction->setEdiTp($tpId);
$transaction->setEdiDocType($docTypeId);
$em->persist($transaction);
} else {
foreach ($result as $key) {
$id = $key->getEdiTpTransactionsId();
$transaction = $em->getRepository('MatrixEdiBundle:EdiTradingPartnerTransactions')->find($id);
$em->remove($transaction);
}
}
$em->flush();
}
return $this->redirect($this->generateUrl('matrix_edi_tpTrans'));
}
Any help would really be appreciated. Thanks in advanced!
The error here is pretty clear: Doctrine handle, at least for relationships, only objects of the "related" (let's call that way) entity.
When you do
$transaction->setEdiTp($tpId);
$transaction->setEdiDocType($docTypeId);
you're trying to insert ID(s) of related objects. This is an error: although your db expects an integer (foreign key), Doctrine is an abstaction "pillow" between your code and db; it choose to work with objects and not with ids(you can see it pretty clearly into entity classes files)
Solution here is pretty simple:
Fetch from db the entity for setEdiTp and setEdiDocType
Pass them to the functions
In PHP (Symfony):
$ediTp = $em
->getRepository('MatrixEdiBundle:EdiTp')
->findOneById($tpId);
$ediDocType = $em
->getRepository('MatrixEdiBundle:EdiDocType')
->findOneById($docTypeId);
then
$transaction->setEdiTp($ediTp);
$transaction->setEdiDocType($ediDocType);
Your error is because setEdiTp need an instance of EdiTradingPartner.
Your error say string given.
Because $tpId is string.
Verify
Change
$transaction->setEdiTp($tpId);
To
// $transaction->setEdiTp($tpId);
var_dump($tpId);
Normally, $tpId return a string, not a object.
So when you call deleteTpTransAction, $tpId must be an instance of setEdiTp
Changement :
$editp = $em->getRepository('MatrixEdiBundle:EdiTradingPartner')->find($tpId);
and change
$transaction->setEdiTp($tpId);
by
$transaction->setEdiTp($editTp);

Symfony2 Datetime format

I'm trying to add a simple comment entity, with the "postedOn" attribute as a Datetime. Whenever I try to add a comment, I get this error :
Error: Call to undefined method Symfony\Component\Validator\Constraints\DateTime::format() in /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php line 53
Any idea ?
Here's the entity code :
<?php
namespace AOFVH\FlyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Comment
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AOFVH\FlyBundle\Entity\CommentRepository")
*/
class Comment
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(name="rating", type="integer")
*/
private $rating;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
protected $postedon;
/**
* #var string
*
* #ORM\Column(name="text", type="text")
*/
private $text;
/**
* #var $commenter
*
* #ORM\ManyToOne(targetEntity="AOFVH\UserBundle\Entity\User", inversedBy="comments", cascade={"persist", "merge"})
*/
private $commenter;
/**
* #var $commenter
*
* #ORM\ManyToOne(targetEntity="AOFVH\FlyBundle\Entity\Flight", inversedBy="comments", cascade={"persist", "merge"})
*/
private $flight;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set rating
*
* #param integer $rating
* #return Comment
*/
public function setRating($rating)
{
$this->rating = $rating;
return $this;
}
/**
* Get rating
*
* #return integer
*/
public function getRating()
{
return $this->rating;
}
/**
* Set text
*
* #param string $text
* #return Comment
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* #return string
*/
public function getText()
{
return $this->text;
}
/**
* Set commenter
*
* #param \AOFVH\UserBundle\Entity\User $commenter
* #return Comment
*/
public function setCommenter(\AOFVH\UserBundle\Entity\User $commenter = null)
{
$this->commenter = $commenter;
return $this;
}
/**
* Get commenter
*
* #return \AOFVH\UserBundle\Entity\User
*/
public function getCommenter()
{
return $this->commenter;
}
/**
* Set flight
*
* #param \AOFVH\FlyBundle\Entity\Flight $flight
* #return Comment
*/
public function setFlight(\AOFVH\FlyBundle\Entity\Flight $flight = null)
{
$this->flight = $flight;
return $this;
}
/**
* Get flight
*
* #return \AOFVH\FlyBundle\Entity\Flight
*/
public function getFlight()
{
return $this->flight;
}
Here are the postedOn getters and setters
/**
* Set postedon
*
* #param \DateTime $postedon
* #return Comment
*/
public function setPostedon($postedon)
{
$this->postedon = $postedon;
return $this;
}
/**
* Get postedon
*
* #return \DateTime
*/
public function getPostedon()
{
return $this->postedon;
}
}
I think it's your mapping in your entity, you don't use "datetime" doctrine format else your form type will try to generate a date with a string for example but for me "postedOn must always be defined on a new comment.You can update your entity constructor with : $this->setPostedOn(new \Datetime()); or you can use TimestampableTrait

Error on update query symfony2

I generated the CRUD for the entity Evenement(event) , which is working. But now I want to update a field in another entity called notification everytime an Evenement is added. Each Evenement has a categorie
Evenement.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Mql14\mqlmeBundle\Entity\Evenement
*
* #ORM\Table(name="evenement")
* #ORM\Entity
*/
class Evenement
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $nom
*
* #ORM\Column(name="nom", type="string", length=45, nullable=true)
*/
private $nom;
/**
* #var datetime $date
*
* #ORM\Column(name="date", type="datetime", nullable=true)
*/
private $date;
/**
* #var string $description
*
* #ORM\Column(name="description", type="string", length=400, nullable=true)
*/
private $description;
/**
* #var integer $ticket
*
* #ORM\Column(name="Ticket", type="integer", nullable=true)
*/
private $ticket;
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="User", mappedBy="evenement")
*/
private $user;
/**
* #var Categorie
*
* #ORM\ManyToOne(targetEntity="Categorie", inversedBy="evenement")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="categorie_id", referencedColumnName="id")
* })
*/
private $categorie;
/**
* #var Lieu
*
* #ORM\ManyToOne(targetEntity="Lieu")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="lieu_id", referencedColumnName="id")
* })
*/
private $lieu;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nom
*
* #param string $nom
*/
public function setNom($nom)
{
$this->nom = $nom;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set date
*
* #param datetime $date
*/
public function setDate($date)
{
$this->date = $date;
}
/**
* Get date
*
* #return datetime
*/
public function getDate()
{
return $this->date;
}
/**
* Set description
*
* #param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set ticket
*
* #param integer $ticket
*/
public function setTicket($ticket)
{
$this->ticket = $ticket;
}
/**
* Get ticket
*
* #return integer
*/
public function getTicket()
{
return $this->ticket;
}
/**
* Add user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function addUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user[] = $user;
}
/**
* Get user
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Set categorie
*
* #param Mql14\mqlmeBundle\Entity\Categorie $categorie
*/
public function setCategorie(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$this->categorie = $categorie;
}
/**
* Get categorie
*
* #return Mql14\mqlmeBundle\Entity\Categorie
*/
public function getCategorie()
{
return $this->categorie;
}
/**
* Set lieu
*
* #param Mql14\mqlmeBundle\Entity\Lieu $lieu
*/
public function setLieu(\Mql14\mqlmeBundle\Entity\Lieu $lieu)
{
$this->lieu = $lieu;
}
/**
* Get lieu
*
* #return Mql14\mqlmeBundle\Entity\Lieu
*/
public function getLieu()
{
return $this->lieu;
}
public function getCategorieId(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$idc= $categorie->getId();
return $idc;
}
}
Categorie.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Mql14\mqlmeBundle\Entity\Categorie
*
* #ORM\Table(name="categorie")
* #ORM\Entity
*/
class Categorie
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $nomcat
*
* #ORM\Column(name="nomCat", type="string", length=45, nullable=true)
*/
private $nomcat;
/**
* #var string $photo
*
* #ORM\Column(name="photo", type="string", length=45, nullable=true)
*/
private $photo;
/**
* #var $evenement
*
* #ORM\OneToMany(targetEntity="Evenement", mappedBy="categorie")
*/
private $evenement;
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="User", mappedBy="categorie")
*/
private $user;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nomcat
*
* #param string $nomcat
*/
public function setNomcat($nomcat)
{
$this->nomcat = $nomcat;
}
/**
* Get nomcat
*
* #return string
*/
public function getNomcat()
{
return $this->nomcat;
}
/**
* Set photo
*
* #param string $photo
*/
public function setPhoto($photo)
{
$this->photo = $photo;
}
/**
* Get photo
*
* #return string
*/
public function getPhoto()
{
return $this->photo;
}
/**
* Add user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function addUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user[] = $user;
}
/**
* Get user
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Add evenement
*
* #param Mql14\mqlmeBundle\Entity\Categorie $evenement
*/
public function addEvenement(\Mql14\mqlmeBundle\Entity\Evenement $evenement)
{
$this->evenement[] = $evenement;
}
/**
* Get evenement
*
* #return Doctrine\Common\Collections\Collection
*/
public function getEvenement()
{
return $this->evenement;
}
}
Notification.php:
<?php
namespace Mql14\mqlmeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Mql14\mqlmeBundle\Entity\Notification
*
* #ORM\Table(name="notification")
* #ORM\Entity
*/
class Notification
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $etat
*
* #ORM\Column(name="etat", type="integer", nullable=true)
*/
private $etat;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="User_id", referencedColumnName="id")
*
* })
*/
private $user;
/**
* #var Categorie
*
* #ORM\ManyToOne(targetEntity="Categorie")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Categorie_id", referencedColumnName="id")
*
* })
*/
private $categorie;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set etat
*
* #param string $etat
*/
public function setEtat($etat)
{
$this->etat = $etat;
}
/**
* Get etat
*
* #return string
*/
public function getEtat()
{
return $this->etat;
}
/**
* Set user
*
* #param Mql14\mqlmeBundle\Entity\User $user
*/
public function setUser(\Mql14\mqlmeBundle\Entity\User $user)
{
$this->user = $user;
}
/**
* Get user
*
* #return Mql14\mqlmeBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set categorie
*
* #param Mql14\mqlmeBundle\Entity\Categorie $categorie
*/
public function setCategorie(\Mql14\mqlmeBundle\Entity\Categorie $categorie)
{
$this->categorie = $categorie;
}
/**
* Get categorie
*
* #return Mql14\mqlmeBundle\Entity\Categorie
*/
public function getCategorie()
{
return $this->categorie;
}
}
In the createAction that was generated after the execution of the CRUD for the Evenement entity I added the update query :
public function createAction(Request $request)
{
$entity = new Evenement();
$request = $this->getRequest();
$form = $this->createForm(new EvenementType(), $entity);
$form->bindRequest($request);
$entity->upload();
$cat=$entity->getCategorie();
if ($cat) {
$catn = $cat->getNomCat();
$query = $this->container->get('doctrine')->getEntityManager()->createQuery( 'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie LIKE :catn ' );
$query->setParameter('categorie', $catn);
$query->execute();
}
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('mql14mqlme_adminshow', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
And the error I'm getting is this:
[Semantical Error] line 0, col 61 near 'categorie LIKE': Error:
Invalid PathExpression. Must be a StateFieldPathExpression.
You set the wrong parameter in the update query.
On this line:
$query = $this->container->get('doctrine')->getEntityManager()->createQuery(
'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1
WHERE n.categorie LIKE :catn' );
$query->setParameter('categorie', $catn);
$query->execute();
It should be:
$query = $this->container->get('doctrine')->getEntityManager()->createQuery(
'UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1
WHERE n.categorie LIKE :catn' );
$query->setParameter('catn', $catn);
$query->execute();
n.categorie is an entity (of type Mql14\mqlmeBundle\Entity\Categorie) and you can't compare entities using LIKE.
Try replacing LIKE with =.
Change
UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie LIKE :catn
To
UPDATE Mql14mqlmeBundle:Notification n SET n.etat=1 WHERE n.categorie = :catn

Use doctrine in a personalized class

I have a Util class in a Symfony 2.4 proyect that get the slug from a book. The slug cannot be repeated. Each slug must be unique. I have the following code form the class that generate the slug. I have the error:
Fatal error: Using $this when not in object context in C:\xampp\htdocs\gens\src\
Sakya\GensBundle\Util\Util.php on line 38
namespace Sakya\GensBundle\Util;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManager;
class Util
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public static function getSlug($slug)
{
$separador = '-';
$tildes=array('á','é','í','ó','ú');
$vocales=array('a','e','i','o','u');
str_replace($vocales,$tildes,$slug);
$slug = iconv('UTF-8', 'ASCII//TRANSLIT', $slug);
$slug = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $slug);
$slug = strtolower(trim($slug, $separador));
$slug = preg_replace("/[\/_|+ -]+/", $separador, $slug);
$i = 1;
while (! $this->em->getRepository("GensBundle:Libro")->findBySlug($slug)){
$slug = $slug."-".$i;
$i++;
}
return $slug;
}
}
It is mi Entity "Libro"
<?php
namespace Sakya\GensBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sakya\GensBundle\Util\Util;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Libro
*
* #ORM\Table()
* #ORM\Entity
*/
class Libro
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="libro", type="string", length=255)
*/
private $libro;
/**
* #ORM\Column(type="string")
*
* #Assert\NotBlank()
*/
protected $slug;
/**
* #var string
*
* #ORM\Column(name="autor", type="string", length=255)
*/
private $autor;
/**
* #var string
*
* #ORM\Column(name="prefacio", type="string", length=700)
*/
private $prefacio;
/**
* #ORM\OneToMany(targetEntity="Capitulo", mappedBy="libro")
*/
private $capitulo;
public function __toString()
{
return $this->getLibro();
}
/**
* Constructor
*/
public function __construct()
{
$this->capitulo = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set libro
*
* #param string $libro
* #return Libro
*/
public function setLibro($libro)
{
$this->libro = $libro;
$this->slug = Util::getSlug($libro);
return $this;
}
/**
* Get libro
*
* #return string
*/
public function getLibro()
{
return $this->libro;
}
/**
* Set autor
*
* #param string $autor
* #return Libro
*/
public function setAutor($autor)
{
$this->autor = $autor;
return $this;
}
/**
* Get autor
*
* #return string
*/
public function getAutor()
{
return $this->autor;
}
/**
* Add capitulo
*
* #param \Sakya\GensBundle\Entity\Capitulo $capitulo
* #return Libro
*/
public function addCapitulo(\Sakya\GensBundle\Entity\Capitulo $capitulo)
{
$this->capitulo[] = $capitulo;
return $this;
}
/**
* Remove capitulo
*
* #param \Sakya\GensBundle\Entity\Capitulo $capitulo
*/
public function removeCapitulo(\Sakya\GensBundle\Entity\Capitulo $capitulo)
{
$this->capitulo->removeElement($capitulo);
}
/**
* Get capitulo
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCapitulo()
{
return $this->capitulo;
}
/**
* Set prefacio
*
* #param string $prefacio
* #return Libro
*/
public function setPrefacio($prefacio)
{
$this->prefacio = $prefacio;
return $this;
}
/**
* Get prefacio
*
* #return string
*/
public function getPrefacio()
{
return $this->prefacio;
}
/**
* Set slug
*
* #param string $slug
* #return Libro
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
}
How can I make a consult that check that the slug is not in the database form the Uti Class?
Thanks for all and sorry for my English
The problem is you are trying refer to a property from static method. Don't do it unless the property is also static.
The best way I can suggest is change the static method into not-static, then create a service from Util class, and make validation outside the entity. It's not a good idea using service inside entity class.
You didn't show the context but I can guess: if you want set slug based on a form - then the best way to achieve what you want would be create a validator.

Resources