I want to install PUGXMultiUserBundle. I followed the documentation of PUGXMultiUserBundle:https://github.com/PUGX/PUGXMultiUserBundle/blob/master/Resources/doc/index.md
I have downloaded the PUGXMultiUserBundle with success and I continued Creating my Entities. I created an entity User:
<?php
namespace Register\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="user")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"societe" = "Societe", "chercheur" = "Chercheur"})
*
*/
abstract class User extends BaseUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $image
* #ORM\Column(name="image", type="string", length=255)
*/
protected $image;
public $file;
protected function getUploadDir()
{
return 'image';
}
protected function getUploadRootDir()
{
return __DIR__.'/../../../../web/'.$this->getUploadDir()."/".$this->getId()."/";
}
public function getWebPath()
{
return null === $this->image ? null : $this->getUploadDir().$this->getId()."/".'/'.$this->image;
}
public function getAbsolutePath()
{
return null === $this->image ? null : $this->getUploadRootDir().$this->getId()."/".'/'.$this->image;
}
public function getAbsolutePath1()
{
return null === $this->image ? null : $this->getUploadRootDir().$this->image;
}
/**
* #ORM\PrePersist
* #ORM\PreUpdate
*/
public function preUpload()
{
if (null !== $this->file) {
// do whatever you want to generate a unique name
$this->image = uniqid().'.'.$this->file->guessExtension();
}
}
/**
* #ORM\PostPersist
* #ORM\PostUpdate
*/
public function upload()
{
if (null === $this->file) {
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->file->move($this->getUploadRootDir(), $this->image);
unset($this->file);
}
/**
* #ORM\PreRemove()
*/
public function storeFilenameForRemove()
{
$this->filenameForRemove = $this->getAbsolutePath1();
}
/**
* #ORM\PostRemove()
*/
public function removeUpload()
{
if ($this->filenameForRemove) {
unlink($this->filenameForRemove);
}
}
}
and the other Entity: societe:
<?php
namespace Register\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use PUGX\MultiUserBundle\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #ORM\Table(name="societe")
* #UniqueEntity(fields = "username", targetClass = "Register\UserBundle\Entity\User", message="fos_user.username.already_used")
* #UniqueEntity(fields = "email", targetClass = "Register\UserBundle\Entity\User", message="fos_user.email.already_used")
*/
class Societe extends User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string $adressemail
*/
protected $adressemail;
/**
* #var string $namesociete
*/
protected $namesociete;
}
an finally the last Entity chercheur:
<?php
namespace Register\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use PUGX\MultiUserBundle\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="chercheur")
* #UniqueEntity(fields = "username", targetClass = "Register\UserBundle\Entity\User", message="fos_user.username.already_used")
* #UniqueEntity(fields = "email", targetClass = "Register\UserBundle\Entity\User", message="fos_user.email.already_used")
*/
class Chercheur extends User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Assert\NotBlank
* #var string
*/
protected $region;
/**
* #Assert\NotBlank
* #var string
*/
protected $firstname;
}
The problem is when I want to generate my entities after : php app/console doctrine:generate:entities Register, a error message appeared in console:
[Doctrine\ORM\Mapping\MappingException]
Class "Register" is not a valid entity or mapped super class.
doctrine:generate:entities [--path="..."] [--no-backup] name
.
Can someone help me to fix this problem and Thank you.
Related
I want to insert into my joint-table RoleUser idUser and idRole ,but in the function I should add an object user and role
How can I do that?
the joint table RoleUser :
/**
* RoleUser
*
* #ORM\Table(name="role_user", indexes={#ORM\Index(name="fk_role_user_id", columns={"ref_user_id"}), #ORM\Index(name="fk_role_id", columns={"ref_role_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\RoleUserRepository")
*/
class RoleUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Role
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Role")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ref_role_id", referencedColumnName="id")
* })
*/
private $refRole;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ref_user_id", referencedColumnName="id")
* })
*/
private $refUser;
/**
* #param Role $refRole
*/
public function setRefRole(\AppBundle\Entity\Role $refRole)
{
$this->refRole = $refRole;
}
/**
* #param User $refUser
*/
public function setRefUser(\AppBundle\Entity\User $refUser)
{
$this->refUser= $refUser;
}
}
In my controller I want to insert the following (for a particular case I should insert in the background, the user can't choose his role):
$user = new User();
$role= new Role();
$roleUser =new RoleUser();
$roleUser->setRefUser($user->getId());
$roleUser->setRefRole(1);
but I konw that I should pass a user and a role :
$roleUser->setRefUser($user);
$roleUser->setRefRole($role);
You need to use a relation ManyToMany instead of OneToMany and remove your Entity RoleUser. you can follow the next example in the documentation official, to mapping this kind of relations.
For the save:
In this case you need to add in the two entities this relation:
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Location
*
* #ORM\Table(name="location")
* #ORM\Entity
*/
class Location
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* <p>Represent the </p>
* #ORM\ManyToMany(targetEntity="LogoLocation", mappedBy="locations")
*/
private $logoLocationCurse;
/**
* Location constructor.
*/
public function __construct()
{
$this->logoLocationCurse = new ArrayCollection();
}
public function addlogoLocationCurse(LogoLocation $location)
{
$this->logoLocationCurse->add($location);
$location->addLocations($this);
}
public function removeLogo(LogoLocation $location)
{
$this->logoLocationCurse->removeElement($location);
$location->removeLocation($this);
}
}
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use \DateTime;
/**
* Class LogoLocation
* #ORM\Table(name="logo_location_curso")
* #ORM\Entity
*/
class LogoLocation
{
/**
* #var integer
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Many Users have Many Groups.
* #ORM\ManyToMany(targetEntity="Location", inversedBy="logocurso")
* #ORM\JoinTable(name="logo_locations")
*/
private $locations;
/**
* LogoLocation constructor.
*/
public function __construct()
{
$this->locations = new ArrayCollection();
}
/**
* #param Location $location
*/
public function addLocations(Location $location)
{
$this->locations->add($location);
}
/**
* #param Location $location
*/
public function removeLocation(Location $location)
{
$this->locations->removeElement($location);
}
/**
*
*/
public function removeLocations()
{
/** #var Location $location */
foreach ($this->locations as $location) {
$location->removeLogo($this);
}
}
}
and make the flush
I need to update password with sonata admin int fos userbundle 'bcrypt' password.
This is my admin class,
<?php
namespace AdminBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class UserAdmin extends Admin {
public function postPersist($object) {
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('id'=>$object->id));
$user->setPlainPassword('test');
$userManager->updateUser($user);
}
This is my user entity,
<?php
// src/AppBundle/Entity/User.php
namespace AdminBundle\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;
/**
* #var string
*
* #ORM\Column(name="telephone", type="text", length=30, nullable=false)
*/
private $telephone;
/**
* Set nonotification
*
* #param text $telephone
* #return User
*/
public function settelephone($telephone) {
$this->telephone = $telephone;
return $this;
}
/**
* Get telephone
*
* #return text
*/
public function gettelephone() {
return $this->telephone;
}
/**
* #var string
*
* #ORM\Column(name="name", type="text", length=60, nullable=false)
*/
private $name;
/**
* Set nonotification
*
* #param text $name
* #return User
*/
public function setname($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return text
*/
public function getname() {
return $this->name;
}
/**
* #var string
*
* #ORM\Column(name="surname", type="text", length=60, nullable=false)
*/
private $surname;
/**
* Set nonotification
*
* #param text $name
* #return User
*/
public function setsurname($surname) {
$this->surname = $surname;
return $this;
}
/**
* Get surname
*
* #return text
*/
public function getsurname() {
return $this->surname;
}
public function __construct() {
parent::__construct();
// your own logic
}
}
But I'm getting this error instead,
Attempted to call an undefined method named "get" of class
"AdminBundle\Admin\UserAdmin". Did you mean to call e.g.
"getActiveSubClass", "getActiveSubclassCode", "getBaseCodeRoute",
"getBaseControllerName", "getBaseRouteName", "getBaseRoutePattern",
"getBatchActions", "getBreadcrumbs", "getChild", "getChildren",
"getClass", "getClassnameLabel", "getCode", "getConfigurationPool",
"getCurrentChild", "getCurrentChildAdmin", "getDataSourceIterator",
"getDatagrid", "getDatagridBuilder", "getExportFields",
"getExportFormats", "getExtensions", "getFilterFieldDescription",
"getFilterFieldDescriptions", "getFilterParameters", "getFilterTheme",
"getForm", "getFormBuilder", "getFormContractor",
"getFormFieldDescription", "getFormFieldDescriptions",
"getFormGroups", "getFormTabs", "getFormTheme", "getIdParameter",
"getLabel", "getLabelTranslatorStrategy", "getList", "getListBuilder",
"getListFieldDescription", "getListFieldDescriptions",
"getManagerType", "getMaxPageLinks", "getMaxPerPage",
"getMenuFactory", "getModelManager", "getNewInstance",
"getNormalizedIdentifier", "getObject", "getObjectIdentifier",
"getObjectMetadata", "getParent", "getParentAssociationMapping",
"getParentFieldDescription", "getPerPageOptions",
"getPermissionsShow", "getPersistentParameter",
"getPersistentParameters", "getRequest", "getRoot", "getRootCode",
"getRouteBuilder", "getRouteGenerator", "getRouterIdParameter",
"getRoutes", "getSecurityHandler", "getSecurityInformation",
"getShow", "getShowBuilder", "getShowFieldDescription",
"getShowFieldDescriptions", "getShowGroups", "getShowTabs",
"getSideMenu", "getSubClasses", "getSubject", "getTemplate",
"getTemplates", "getTranslationDomain", "getTranslationLabel",
"getTranslator", "getUniqid", "getUrlsafeIdentifier" or
"getValidator"?
It would be great help someone can look into it.
You cannot access the container with $this->get('service.name') from a sonata admin class. You should use:
$container = $this->getConfigurationPool()->getContainer();
$userManager = $container->get('fos_user.user_manager');
Also, I don't know if your solution would work anyway. I would use something like this:
public function postPersist($object) {
$container = $this->getConfigurationPool()->getContainer();
$entityManager = $container->get('doctrine.orm.entity_manager');
$object->setPlainPassword('test');
$entityManager->persist($user);
$entityManager->flush();
}
And do yourself a favor and respect the naming conventions (getName instead of getname, etc)
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.
Here some context information: I'm building a Symfony2 application with Doctrine2 and FOSRestBundle.
My problem: I want to be able to create a parent with his children with just one JSON and one database access.
My JSON looks like this:
{
"name": "TEST_NAME",
"info": "TEST_INFO",
"cmts": [
{
"cmt": "CMT1",
"info": "INFO1"
},
{
"cmt": "CMT2",
"info": "INFO2"
},
{
"cmt": "CMT3",
"info": "INFO3"
}
]
}
Here is my TEST entity:
<?php
namespace App\Bundle\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Test
*
* #ORM\Table(name="Test")
* #ORM\Entity(repositoryClass="App\Bundle\DemoBundle\Entity\TestRepository")
*/
class Test
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank()
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="info", type="string", length=255, nullable=true)
*/
private $info;
/**
* #ORM\OneToMany(targetEntity="TestCmt", mappedBy="test", fetch="EAGER", orphanRemoval=true, cascade={"merge", "remove", "persist"})
*/
protected $cmts;
/**
* Constructor
*/
public function __construct()
{
$this->cmts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add cmts
*
* #param \App\Bundle\DemoBundle\Entity\TestCmt $cmts
* #return Test
*/
public function addCmt(\App\Bundle\DemoBundle\Entity\TestCmt $cmts)
{
$this->cmts[] = $cmts;
return $this;
}
/**
* Remove cmts
*
* #param \App\Bundle\DemoBundle\Entity\TestCmt $cmts
*/
public function removeCmt(\App\Bundle\DemoBundle\Entity\TestCmt $cmts)
{
$this->cmts->removeElement($cmts);
}
/**
* Get cmts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCmts()
{
return $this->cmts;
}
// other getters/setters...
}
And my TESTCMT entity:
<?php
namespace App\Bundle\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TestCmt
*
* #ORM\Table(name="TestCmt")
* #ORM\Entity(repositoryClass="App\Bundle\DemoBundle\Entity\TestCmtRepository")
*/
class TestCmt
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="cmt", type="string", length=255)
*/
private $cmt;
/**
* #var string
*
* #ORM\Column(name="info", type="string", length=255, nullable=true)
*/
private $info;
/**
* #var Test
*
* #ORM\ManyToOne(targetEntity="Test", inversedBy="cmts")
* #ORM\JoinColumn(name="test_id", referencedColumnName="id")
**/
private $test;
/**
* Set test
*
* #param \App\Bundle\DemoBundle\Entity\Test $test
* #return TestCmt
*/
public function setTest(\App\Bundle\DemoBundle\Entity\Test $test = null)
{
$this->test = $test;
return $this;
}
/**
* Get test
*
* #return \App\Bundle\DemoBundle\Entity\Test
*/
public function getTest()
{
return $this->test;
}
}
And finaly my postTestAction():
public function postTestAction(Request $request)
{
$entity = $this->deserialize($request, 'App\DemoBundle\Entity\Test');
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $entity;
}
When I send the JSON, TEST and TESTCMTs are created. Nevertheless, all "test_id" from the created TESTCMTs are "null"... And that's my problem!
EDIT: with SQL Server Profiler, I can see that Doctrine make that Transact SQL request:
INSERT INTO TESTCMT (test_id, cmt, info) VALUES (null, 'CMT', 'INFO')
I don't know why Doctrine can't send the test_id... TEST is created before TESTCMT, so "test_id" should be reachable for Doctrine to create the associate TESTCMTs.
Can someone helped me to fix it? :)
Remove #ORM\GeneratedValue(strategy="AUTO") and it won't let the DB generate a new id for the Entity
Im using Gedmo Translatable in my project.
I have Product entity and Inclusion entity.
Relation between them is ManyToMany.
Product Entity
namespace Traffic\ShopBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Traffic\ShopBundle\Model\Product as ProductModel;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity(repositoryClass="Traffic\ShopBundle\Repository\ProductRepository")
* #Gedmo\TranslationEntity(class="Traffic\ShopBundle\Entity\ProductTranslation")
*
*/
class Product extends ProductModel {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
* #Gedmo\Translatable
*
* #var type string
*/
protected $name;
/**
* #ORM\ManyToMany(targetEntity="Inclusion")
* #ORM\JoinTable(name="product_inclusion",
* joinColumns={#ORM\JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="inclusion_id", referencedColumnName="id")}
* )
*
* #var type Collection
*/
protected $inclusions;
/**
* #ORM\OneToMany(
* targetEntity="ProductTranslation",
* mappedBy="object",
* cascade={"persist", "remove"}
* )
*/
protected $translations;
.....
}
Inclusion Entity
namespace Traffic\ShopBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Traffic\ShopBundle\Model\Inclusion as InclusionModel;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity(repositoryClass="Traffic\AdminBundle\Repository\TranslatableRepository")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"sauce" = "Sauce", "topping" = "Topping"})
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
* #Gedmo\TranslationEntity(class="Traffic\ShopBundle\Entity\InclusionTranslation")
*
* #ORM\Table(name="inclusion")
*/
class Inclusion extends InclusionModel {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
* #Gedmo\Translatable
*
* #var type string
*/
protected $name;
/**
* #ORM\OneToMany(
* targetEntity="InclusionTranslation",
* mappedBy="object",
* cascade={"persist", "remove"}
* )
*/
protected $translations;
.......
}
In my Repository class I have a method to fetch translated object, but it just translates my Product not Inclusions
namespace Traffic\ShopBundle\Repository;
use Traffic\AdminBundle\Repository\TranslatableRepository;
use Traffic\ShopBundle\Entity\Kiosk;
/**
* Description of FinancialTransactionRepository
*
* #author bart
*/
class ProductRepository extends TranslatableRepository {
public function findAllProductsForKiosk(Kiosk $kiosk, $locale = "es"){
$qb = $this->createQueryBuilder("p")
->leftJoin('p.kiosks', 'k')
->leftJoin('p.flavours', 'f')
->leftJoin('p.inclusions', "i")
->leftJoin('p.type', "t")
->where('k.kiosk = :kiosk')
;
$qb->setParameter("kiosk", $kiosk);
$results = $this->getTranslatedQuery($qb, $locale);
return $results->execute();
}
}
and getTranslatedQuery
/**
* Returns translated Doctrine query instance
*
* #param QueryBuilder $qb A Doctrine query builder instance
* #param string $locale A locale name
*
* #return Query
*/
protected function getTranslatedQuery(QueryBuilder $qb, $locale = null)
{
$locale = null === $locale ? $this->defaultLocale : $locale;
$query = $qb->getQuery();
$query->setHint(
Query::HINT_CUSTOM_OUTPUT_WALKER,
'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
);
$query->setHint(TranslatableListener::HINT_TRANSLATABLE_LOCALE, $locale);
return $query;
}
Is there a way to fetch all translated objects with one query?
Maybe you should change hydration mode?
$query->setHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION);
$config = $this->container->get('doctrine')->getManager()->getConfiguration();
if ($config->getCustomHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION) === null) {
$config->addCustomHydrationMode(
TranslationWalker::HYDRATE_OBJECT_TRANSLATION,
'Gedmo\\Translatable\\Hydrator\\ORM\\ObjectHydrator'
);
}