Symfony and Doctrine databases - symfony

I am working on some new project and the project is nearly done using Symfony framework, but the problem that i am used to CodeIgnitor Framework and basically as a Java developer/Android a lot of stuff i got confused with when working on Web development so here is the situation:
The website have a user end and an admin end (i am working on the Admin end), so there are these tables in the database which i really don't understand why they are built like this but this is not the problem
what i would like to know is how to add a service_category field with the corresponding translations in the service_category_translation using forms or any other way
this is the ServiceCategory Entity
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use JMS\Serializer\Annotation as Serializer;
/**
* class ServiceCategory
*
* #ORM\Table(name="service_category")
* #ORM\Entity
*
* #Serializer\ExclusionPolicy("all")
*/
class ServiceCategory
{
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\SoftDeletable\SoftDeletable;
use ORMBehaviors\Translatable\Translatable;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
* #Serializer\Expose
* #Serializer\Groups({"general-information", "service-offer"})
*/
private $id;
/**
* #var ServiceGroup
*
* #ORM\OneToMany(targetEntity="ServiceGroup", mappedBy="serviceCategory")
*
* #Serializer\Expose
* #Serializer\Groups({"service-offer"})
*/
private $serviceGroup;
/**
* Constructor
*/
public function __construct()
{
$this->serviceGroup = new ArrayCollection();
}
/**
* {#inheritdoc}
*/
public function __toString()
{
return $this->getName() ? $this->getName() : '';
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Get translated name
*
* #return string
*
* #Serializer\VirtualProperty
* #Serializer\SerializedName("name")
* #Serializer\Groups({"invoice-list", "service-offer"})
*/
public function getName()
{
if($this->getTranslations()->get($this->getCurrentLocale()) == null){
return 'sorry';
}
return $this->getTranslations()->get($this->getCurrentLocale())->getName();
}
/**
* Add serviceGroup
*
* #param ServiceGroup $serviceGroup
*
* #return ServiceCategory
*/
public function addServiceGroup(ServiceGroup $serviceGroup)
{
$this->serviceGroup[] = $serviceGroup;
return $this;
}
/**
* Remove serviceGroup
*
* #param ServiceGroup $serviceGroup
*/
public function removeServiceGroup(ServiceGroup $serviceGroup)
{
$this->serviceGroup->removeElement($serviceGroup);
}
/**
* Get serviceGroup
*
* #return Collection
*/
public function getServiceGroup()
{
return $this->serviceGroup;
}
}
and this is the ServiceCategoryTranslation Entity
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Class ServiceCategoryTranslation
*
* #package CoreBundle\Entity
*
* #ORM\Entity
* #ORM\Table(name="service_category_translation")
*/
class ServiceCategoryTranslation
{
use ORMBehaviors\Translatable\Translation;
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\SoftDeletable\SoftDeletable;
/**
* #ORM\Column(type="string", length=255)
*/
protected $name;
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #param string
* #return null
*/
public function setName($name)
{
$this->name = $name;
}
public function __toString() {
return $this->name;
}
}
how can i achieve this ?
please don't guide me to symfony or doctrine documentation i have been lost there for two days now and i am running late on the schedule
Thanks in advance

You have a one-to-many-association from ServiceCategory (1) to ServiceCategoryTranslations (many) since I assume you
will manage the transaltions from the category. This have to be a bidirectional association, have a look
here
You have to add a property to manage the entities and describe the association. I will do it with annotations.
use Doctrine\Common\Collections\ArrayCollection;
class ServiceCategory
{
/**
* #OneToMany(targetEntity="ServiceCategoryTranslation", mappedBy="serviceCategory")
**/
private $translations;
public function __construct()
{
$this->translations = new ArrayCollection();
}
/**
* #return ServiceCategoryTranslation[]
*/
public function getStandort(){
return $this->translations;
}
/**
* #param ArrayCollection $translations
* #return ServiceCategory
*/
public function setTranslations(ArrayCollection $translations)
{
$this->translations->clear();
foreach ($translations as $translation){
$this->addTranslation($translation);
}
return $this;
}
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategory
*/
public function addTranslation(ServiceCategoryTranslation $translation){
/* this is a way to keep the integerity */
$translation->setServiceCategory($this);
if(!$this->translation){
$this->translations = new ArrayCollection();
}
$this->translations->add($translation);
return $this;
}
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategory
*/
public function removeStandort(ServiceCategoryTranslation $translation){
$this->translations->removeElement($translation);
return $this;
}
}
class ServiceCategoryTranslation
{
/**
* #ManyToOne(targetEntity="ServiceCategory", inversedBy="translations")
* #JoinColumn(name="translatable_id", referencedColumnName="id")
**/
private $serviceCategory;
/**
* #param ServiceCategoryTranslation $translation
* #return ServiceCategoryTranslation
*/
public function setServiceCategory(ServiceCategory $serviceCategory){
$this->serviceCategory = $serviceCategory;
return $this;
}
/* getter analog */
}

Related

API Platform Sonata Media Bundle Gallery - Circular Reference

New in SF3, I use API Platform and Sonata Media Bundle.
I'm blocked while getting Gallery entity of Sonata using API Platform GET request.
"A circular reference has been detected when serializing the object of class \"Application\\Sonata\\MediaBundle\\Entity\\Gallery\" (configured limit: 1)"
The admin of the entity works great, I can add a gallery to the entity.
When the entity have a gallery it cause this error, when it does not it's ok.
Entity Technic
GET /technics in API Platform
[
{
"id": 0,
"type": "string",
"comment": "string",
"links": [
"string"
],
"gallery": "string"
}
]
Entity Class
<?php
// src/AppBundle/Entity/Technic.php
namespace AppBundle\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity
* #ApiResource
*/
class Technic
{
/**
* #var int The id of this evaluation.
*
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* #var string $type TechnicType of the evaluation
*
* #ORM\OneToOne(targetEntity="TechnicType")
* #Assert\NotBlank
*/
public $type;
/**
* #var string $note Note of the evaluation
*
* #ORM\Column(type="string", length=255, nullable=true)
*/
public $comment;
/**
* #var Link[] Link Links of this technic.
*
* #ORM\ManyToMany(targetEntity="Link", cascade={"persist"})
*/
private $links;
/**
* #ORM\OneToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Gallery",cascade={"persist"})
* #ORM\JoinColumn(name="gallery", referencedColumnName="id", nullable=true)
*/
private $gallery;
/**
* Constructor
*/
public function __construct()
{
$this->links = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set type
*
* #param \AppBundle\Entity\TechnicType $type
*
* #return Technic
*/
public function setType(\AppBundle\Entity\TechnicType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return \AppBundle\Entity\TechnicType
*/
public function getType()
{
return $this->type;
}
/**
* Add link
*
* #param \AppBundle\Entity\Link $link
*
* #return Technic
*/
public function addLink(\AppBundle\Entity\Link $link)
{
$this->links[] = $link;
return $this;
}
/**
* Remove link
*
* #param \AppBundle\Entity\Link $link
*/
public function removeLink(\AppBundle\Entity\Link $link)
{
$this->links->removeElement($link);
}
/**
* Get links
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLinks()
{
return $this->links;
}
/**
* Set comment
*
* #param string $comment
*
* #return Technic
*/
public function setComment($comment)
{
$this->comment = $comment;
return $this;
}
/**
* Get comment
*
* #return string
*/
public function getComment()
{
return $this->comment;
}
/**
* Set gallery
*
* #param \Application\Sonata\MediaBundle\Entity\Gallery $gallery
*
* #return Technic
*/
public function setGallery(\Application\Sonata\MediaBundle\Entity\Gallery $gallery = null)
{
$this->gallery = $gallery;
return $this;
}
/**
* Get gallery
*
* #return \Application\Sonata\MediaBundle\Entity\Gallery
*/
public function getGallery()
{
return $this->gallery;
}
}
Thank a lot guys, I'm desesperate I try a lot of things in StackQ/A, annotations, seraliazer config...
You need to configure serialization correctly. Either setup serialization groups, so that on GETting some entity serializer would only pick (for example) IDs of related entities, or set up circualr reference handler in normalizer and inject this normalizer into serializer.
$normalizer = new GetSetMethodNormalizer();
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
There might be more specific answer for api-platform, which I don't know, because serialization of related entities is popular issue.

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;

Doctrine 2 - ManyToMany relationship - empty collection

I have many to many relationship between user and groups, but when I want to access all groups for user I get empty collection.
namespace LoginBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="User")
*/
class User
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="login", length=45)
*/
private $_sLogin;
/**
* #ORM\ManyToMany(targetEntity="GroupBundle\Entity\Group", inversedBy="_aUser")
* #ORM\JoinTable(name="Group_x_User",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $_aGroup;
public function __construct() {
$this->_aGroup = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sLogin
*
* #param string $sLogin
*
* #return User
*/
public function setLogin($sLogin)
{
$this->_sLogin = $sLogin;
return $this;
}
/**
* Get sLogin
*
* #return string
*/
public function getLogin()
{
return $this->_sLogin;
}
public function getGroups()
{
return $this->_aGroup;
}
User and Group use Group_x_User table to store their relationships.
namespace GroupBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="Group")
*/
class Group
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="name", length=45)
*/
private $_sName;
/**
* #ORM\ManyToMany(targetEntity="LoginBundle\Entity\User", mappedBy="_aGroup")
*/
private $_aUser;
public function __construct() {
$this->_aUser = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sName
*
* #param string $sName
*
* #return Group
*/
public function setName($sName)
{
$this->_sName = $sName;
return $this;
}
/**
* Get sName
*
* #return string
*/
public function getName()
{
return $this->_sName;
}
public function getUsers()
{
return $this->_aUser;
}
}
For restoring data from database I use code:
$oUser = $this->getDoctrine()
->getRepository('LoginBundle:User')
->find(2);
$aGroup = $oUser->getGroups();
Unfortunatelly $aGroup collection contains array of 0 elements while in database are records which are matching. What am I missing in my mapping?
There is something missing from your User class. You only declare _aGroup with ArrayCollection. This is not enough. You have to store the data into ArrayCollection.
Add this into User class.
public class addGroups(\GroupBundle\Entity\Group $group)
{
$group->addUsers($this);
$this->_aGroup->add($group);
}
This is for Group class.
public class addUsers(\LoginBundle\Entity\User $user)
{
if (!$this->_aUser->contains($user)) {
$this->_aUser->add($user);
}
}
For more information, you can visit this link.
#ORM\JoinTable() annotation syntax on User::$_aGroup definition is intended to be used for self-referencing relations Doctrine documentation.
Try using simplified syntax :
#JoinTable(name="Group_x_User")
If you use common conventions ('id' as column name for identifiers, and so on) Doctrine and Symfony will do the rest for you.

Symfony 2 doctrine DQL order by two fields

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.

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