AppBundle\\Entity\\User#$class_cat\", got \"integer\" instead - symfony

Hi i got this error while data insert in database please let me know where is the problem i am new in symfony
"Expected value of type \"AppBundle\Entity\Class_cat\" for
association field \"AppBundle\Entity\User#$class_cat\", got
\"integer\" instead.",
"class": "Doctrine\ORM\ORMInvalidArgumentException"
this is User entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User
{
/**
* Constructor
*/
public function __construct()
{
$this->class_cat = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=255)
*/
private $role;
/**
* #ORM\ManyToOne(targetEntity="Class_cat", inversedBy="users")
* #ORM\JoinColumn(name="class_id", referencedColumnName="id")
*/
private $class_cat;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set role
*
* #param string $role
*
* #return User
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return string
*/
public function getRole()
{
return $this->role;
}
/**
* #return mixed
*/
public function getClassCat()
{
return $this->class_cat;
}
/**
* #param mixed $class_cat
*/
public function setClassCat($class_cat)
{
$this->class_cat = $class_cat;
}
this is class_cat enity
class Class_cat {
/**
* Constructor
*/
public function __construct()
{
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="class_name", type="string", length=255)
*/
private $className;
/**
* #ORM\OneToMany(targetEntity="User", mappedBy="class_cat")
*/
protected $users;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set className
*
* #param string $className
*
* #return Class_cat
*/
public function setClassName($className)
{
$this->className = $className;
return $this;
}
/**
* Get className
*
* #return string
*/
public function getClassName()
{
return $this->className;
}
public function getUsers()
{
return $this->users;
}
/**
* #param mixed $users
*/
public function setUsers($users)
{
$this->users = $users;
}
this is controller code
> public function postAction(Request $request)
> {
> $data = new User;
> $name = $request->get('name');
> $role = $request->get('role');
> $class = $request->get('class_id');
> if (empty($name) || empty($role) || empty($class)) {
> return new View("NULL VALUES ARE NOT ALLOWED", Response::HTTP_NOT_ACCEPTABLE);
> }
> $data->setName($name);
> $data->setRole($role);
> $data->setClassId(1);
> $em = $this->getDoctrine()->getManager();
> $em->persist($data);
> $em->flush();
> return new View("User Added Successfully", Response::HTTP_OK);
> }

You need to pass the entity not the id for example:
$em = $this->getDoctrine()->getManager();
$classCat = $em->getRepository('AppBundle:ClassCat')->find(1);
$data->setClassCat($classCat);

Hi instead of passing integer value you need to pass an object of class Class_cat.
When you mapped any entity field to any other entity symfony need object to set.
So your solution is simple to try something like this:
public function postAction(Request $request){
$em = $this->getDoctrine()->getManager();
$data = new User;
$name = $request->get('name');
$role = $request->get('role');
$class = $request->get('class_id');
if (empty($name) || empty($role) || empty($class)) {
return new View("NULL VALUES ARE NOT ALLOWED",
Response::HTTP_NOT_ACCEPTABLE);
}
$classCat = $em->getRepository('AppBundle:ClassCat')->find($class);
$data->setName($name);
$data->setRole($role);
$data->setClassId($classCat);
$em->persist($data);
$em->flush();
return new View("User Added Successfully", Response::HTTP_OK);
}

Instead of integer value in
use object like this:
$data->setClassId(1);
$em = $this->getDoctrine()->getManager();
$classCat = $em->getRepository('AppBundle:ClassCat')->find(1);
$data->setClassCat($classCat);

Related

Doctrine: ManyToMany matching criteria set wrong expressions

I have two entities: User and Event, they are in ManyToMany relationship.
I try to match events by criteria from $user->getEvents() but get nothing. After checking profiler i saw that criteria did not work correctly while build sql, i used expression lte and gte but in sql doctrine continue to use =.
Here are my classes.
User:
<?php
namespace App\UserBundle\Entity;
use App\CoreBundle\Entity\Event;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use JMS\Serializer\Annotation as JMS;
/**
* #JMS\ExclusionPolicy("all")
*
* #ORM\Entity(repositoryClass="App\UserBundle\Repository\UserRepository")
* #ORM\Table(name="users", uniqueConstraints={#ORM\UniqueConstraint(name="User",columns={"login", "email"})})
* #UniqueEntity(fields={"login","email"})
* #ORM\HasLifecycleCallbacks()
*/
class User
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="login", type="string", length=255, unique=true, nullable=false)
* #Assert\NotBlank()
*/
protected $login;
/**
* #JMS\Expose
*
* #ORM\Column(name="name", type="string", length=255, unique=true, nullable=false)
* #Assert\NotBlank()
*/
protected $name;
/**
* #JMS\Expose
*
* #ORM\Column(name="email", type="string", length=255, unique=true, nullable=false)
* #Assert\NotBlank()
*/
protected $email;
/**
* #ORM\Column(name="roles", type="array", nullable=false)
* #Assert\NotBlank()
*/
protected $roles;
/**
* #ORM\Column(name="blocked", type="boolean")
* #Assert\NotBlank()
*/
protected $blocked;
/**
* #ORM\Column(type="datetime")
*/
protected $created;
/**
* #ORM\Column(type="datetime")
*/
protected $updated;
/**
* #ORM\ManyToMany(targetEntity="App\CoreBundle\Entity\Event", inversedBy="users", cascade={"persist", "remove"})
* #ORM\JoinTable(name="users_events",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="cascade")},
* inverseJoinColumns={#ORM\JoinColumn(name="event_id", referencedColumnName="id", onDelete="cascade")}
* )
*/
protected $events;
public function __construct()
{
$this->roles = array();
$this->events = new ArrayCollection();
$this->setCreated(new \DateTime());
$this->setUpdated(new \DateTime());
}
public function __toString()
{
return (string) $this->id;
}
/**
* #ORM\PreUpdate
*/
public function setUpdatedValue()
{
$this->setUpdated(new \DateTime());
}
/**
* Set created.
*
* #param \DateTime $created
*
* #return User
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created.
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated.
*
* #param \DateTime $updated
*
* #return User
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated.
*
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
public function getId()
{
return $this->id;
}
/**
* Get Login.
*
* #return string
*/
public function getLogin()
{
return $this->login;
}
/**
* Set Login.
*
* #param $login
*
* #return User
*/
public function setLogin($login)
{
$this->login = $login;
return $this;
}
/**
* Get Name.
*
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* Set Name.
*
* #param string $name
*
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get Email.
*
* #return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* Set Email.
*
* #param mixed $email
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get roles.
*
* #return mixed
*/
public function getRoles()
{
return $this->roles;
}
/**
* Set Roles.
*
* #param mixed $roles
*
* #return User
*/
public function setRoles($roles)
{
$this->roles = array();
foreach ($roles as $role) {
$this->addRole($role);
}
return $this;
}
/**
* Add role to collection.
*
* #param $role
*
* #return User
*/
public function addRole($role)
{
$role = strtoupper($role);
if (!in_array($role, $this->roles, true)) {
$this->roles[] = $role;
}
return $this;
}
/**
* Get Blocked.
*
* #return boolean
*/
public function getBlocked()
{
return $this->blocked;
}
/**
* Set Blocked.
*
* #param boolean $blocked
*
* #return User
*/
public function setBlocked($blocked)
{
$this->blocked = $blocked;
return $this;
}
/**
* Add event.
*
* #param Event $event
*
* #return User
*/
public function addEvent(Event $event)
{
if (!$this->events->contains($event)) {
$this->events[] = $event;
}
return $this;
}
/**
* Remove event.
*
* #param Event $event
*
* #return User
*/
public function removeEvent(Event $event)
{
if ($this->events->contains($event)) {
$this->events->removeElement($event);
}
return $this;
}
/**
* Get events.
*
* #return ArrayCollection
*/
public function getEvents()
{
return $this->events;
}
}
Event:
<?php
namespace App\CoreBundle\Entity;
use App\UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Event
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="App\CoreBundle\Repository\EventRepository")
*/
class Event
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="event_name", type="string", length=50)
*/
private $eventName;
/**
* #var string
*
* #ORM\Column(name="event_description", type="string", length=160)
*/
private $eventDescription;
/**
* #var string
*
* #ORM\Column(name="event_type", type="string", length=100)
*/
private $eventType;
/**
* #var boolean
*
* #ORM\Column(name="visible", type="boolean")
*/
private $visible;
/**
* #var \DateTime
*
* #ORM\Column(name="start_date", type="datetime")
*/
private $startDate;
/**
* #var \DateTime
*
* #ORM\Column(name="end_date", type="datetime")
*/
private $endDate;
/**
* #ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", mappedBy="events")
*/
protected $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set eventName
*
* #param string $eventName
* #return Event
*/
public function setEventName($eventName)
{
$this->eventName = $eventName;
return $this;
}
/**
* Get eventName
*
* #return string
*/
public function getEventName()
{
return $this->eventName;
}
/**
* Set eventDescription
*
* #param string $eventDescription
* #return Event
*/
public function setEventDescription($eventDescription)
{
$this->eventDescription = $eventDescription;
return $this;
}
/**
* Get eventDescription
*
* #return string
*/
public function getEventDescription()
{
return $this->eventDescription;
}
/**
* Set eventType
*
* #param string $eventType
* #return Event
*/
public function setEventType($eventType)
{
$this->eventType = $eventType;
return $this;
}
/**
* Get eventType
*
* #return string
*/
public function getEventType()
{
return $this->eventType;
}
/**
* Set visible
*
* #param boolean $visible
* #return Event
*/
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
/**
* Get visible
*
* #return boolean
*/
public function getVisible()
{
return $this->visible;
}
/**
* Set startDate
*
* #param \DateTime $startDate
* #return Event
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this;
}
/**
* Get startDate
*
* #return \DateTime
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Set endDate
*
* #param \DateTime $endDate
* #return Event
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this;
}
/**
* Get endData
*
* #return \DateTime
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* Set users.
*
* #param ArrayCollection $users
*
* #return Event
*/
public function setUsers(ArrayCollection $users)
{
$this->users = $users;
return $this;
}
/**
* Add user.
*
* #param User $user
*
* #return Event
*/
public function addUser(User $user)
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
/**
* Get user.
*
* #return User
*/
public function getUsers()
{
return $this->users;
}
/**
* Remove user
*
* #param User $user
*/
public function removeUser(User $user)
{
$this->users->removeElement($user);
}
}
And here is how i try to find events related to user:
private function getActiveEventsCriteria($camelStyle = true, $dateAsObject = true)
{
$currentDateTime = new \DateTime();
$criteria = Criteria::create()
->where(
Criteria::expr()->andX(
Criteria::expr()->lte($camelStyle ? 'startDate' : 'start_date', $dateAsObject ? $currentDateTime : $currentDateTime->format("Y-m-d H:i:s")),
Criteria::expr()->gte($camelStyle ? 'endDate' : 'end_date', $dateAsObject ? $currentDateTime : $currentDateTime->format("Y-m-d H:i:s"))
)
)
->andWhere(Criteria::expr()->eq('visible', 1));
return $criteria;
}
public function getParticipatingEventsBy(User $user)
{
$userEvents = $user->getEvents();
if (is_null($userEvents)) return [];
return $userEvents->matching($this->getActiveEventsCriteria(false, false));
}
$this->getParticipatingEventsBy($user);
In profiler/debug i see next sql:
SELECT
te.id AS id,
te.event_name AS event_name,
te.event_description AS event_description,
te.event_type AS event_type,
te.visible AS visible,
te.start_date AS start_date,
te.end_date AS end_date
FROM
event te
JOIN users_events t ON t.event_id = te.id
WHERE
t.user_id = ?
AND te.start_date = ?
AND te.end_date = ?
AND te.visible = ?
And with applied parameters:
SELECT
te.id AS id,
te.event_name AS event_name,
te.event_description AS event_description,
te.event_type AS event_type,
te.visible AS visible,
te.start_date AS start_date,
te.end_date AS end_date
FROM
event te
JOIN users_events t ON t.event_id = te.id
WHERE
t.user_id = 14 AND
te.start_date = '2015-12-03 16:26:44' AND
te.end_date = '2015-12-03 16:26:44' AND
te.visible = 1;
I changed WHERE to next:
WHERE
t.user_id = 14 AND
te.start_date <= '2015-12-03 16:26:44' AND
te.end_date >= '2015-12-03 16:26:44' AND
te.visible = 1;
And with that sql i got correct result.
When i use same criteria right with repository without relation to user - everything is ok:
public function getActiveEvents() {
return $this->matching($this->getActiveEventsCriteria());
}
public function matching(Criteria $criteria)
{
return $this->repository->matching($criteria);
}
$this->getActiveEvents();
This is formatted sql:
SELECT
t0.id AS id_1,
t0.event_name AS event_name_2,
t0.event_description AS event_description_3,
t0.event_type AS event_type_4,
t0.visible AS visible_5,
t0.start_date AS start_date_6,
t0.end_date AS end_date_7
FROM
event t0
WHERE
(
(
t0.start_date <= ?
AND t0.end_date >= ?
)
AND t0.visible = ?
)
And with applied parameters:
SELECT
t0.id AS id_1,
t0.event_name AS event_name_2,
t0.event_description AS event_description_3,
t0.event_type AS event_type_4,
t0.visible AS visible_5,
t0.start_date AS start_date_6,
t0.end_date AS end_date_7
FROM
event t0
WHERE
((t0.start_date <= '2015-12-03 17:01:47' AND t0.end_date >= '2015-12-03 17:01:47') AND
t0.visible = 1);
As you can see, for case when i dont try to search through relation - everything is ok, i get result. But when i try related events to user with use of Criteria - it fails and return empty result cause of incorrect sql.
I use php 5.6.*, symfony 2.8, doctrine 2.5.2, latest MySQL.
Any help will be very appreciated.
Thank you.
UPDATE:
- created issue in JIRA: here

How to insert data with foriegn key in symfony 2 API

curl -v -H "Content-Type: application/json" -d "{\"user\":1,\"userapikey\":\"aaaaaaaaaaaaaaaaaa\",\"title\":\"test tile\"}" http://localhost/us/serenify/web/app_dev.php/userapi/create
I am passing data for creating a apikey record for a specific user.
In above expression user is forign key from user master table.
public function processform(ApiKey $apikey,Request $request)
{
$apiuser = new ApiUser();
$apiform = $this->createForm(new ApiKeyType(), $apikey);
$apiform->submit($request);
if($apiform->isValid())
{
// $page = $apiform->getData();
$content = json_decode($request->getContent());
$apikey->setUserApikey($content->userapikey);
$apikey->setTitle($content->title);
$em = $this->getDoctrine()->getManager();
$em->persist($apikey);
$em->flush();
$data=array(
"success"=>'true',
"msg"=>'Record inserted!'
);
$response = new Response(json_encode($data));
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'application/json');
}
else
{
$out=array(
"success"=>'true',
"msg"=>'invalid form data!'
);
$response = new Response(json_encode($out));
$response->setStatusCode(204);
$response->headers->set('Content-Type', 'application/json');
}
return $response;
}
This is my controller.
class ApiKey
{
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="ApiUser", inversedBy="apikey",cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="userapikey", type="string", length=255)
*/
private $userapikey;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set apikey
*
* #param string $userapikey
* #return userapi
*/
public function setUserApikey($userapikey)
{
$this->userapikey = $userapikey;
return $this;
}
/**
* Get apikey
*
* #return string
*/
public function getUserApikey()
{
return $this->userapikey;
}
/**
* Set title
*
* #param string $title
* #return userapi
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Get user
*
* #return integer
*/
public function getUser()
{
return $this->user;
}
/**
* Set User
*
* #param integer $user
* #return userapi
*/
public function setUser(ApiUser $value = null)
{
$this->user = $value;
return $this;
}
}
And the class ApiUser
class ApiUser
{
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="ApiKey", mappedBy="apiuser")
*/
private $apikeys;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255)
* #Assert\NotBlank()
*/
private $username;
/**
* #var string
* #Assert\NotBlank()
*
* #ORM\Column(name="userpassword", type="string", length=255)
*/
private $userpassword;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return user
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set userpassword
*
* #param string $userpassword
* #return user
*/
public function setUserpassword($userpassword)
{
$this->userpassword = $userpassword;
return $this;
}
/**
* Get userpassword
*
* #return string
*/
public function getUserpassword()
{
return $this->userpassword;
}
}
& this are entity classes.
Please help to insert record, right now NULL value is getting inserted in userid column.
You need a DataTransformer: http://symfony.com/doc/current/cookbook/form/data_transformers.html
class UserToIdTransformer implements DataTransformerInterface
{
/**
* #var ObjectManager
*/
private $om;
/**
* #param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object (user) to an int (id).
*
* #param User|null $user
* #return integer
*/
public function transform($user)
{
if (null === $user) {
return "";
}
return $user->getId();
}
/**
* Transforms an integer (id) to an object (User).
*
* #param integer $number
*
* #return User|null
*
* #throws TransformationFailedException if object (user) is not found.
*/
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$user = $this->om
->getRepository('YourBundle:User')
->find($id);
if (null === $user) {
throw new TransformationFailedException(sprintf(
'An user with id "%s" does not exist!',
$id
));
}
return $user;
}
}
Then in your formtype, while adding the field:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
// this assumes that the entity manager was passed in as an option
$entityManager = $options['em'];
$transformer = new UserToIdTransformer($entityManager);
// add a normal text field, but add your transformer to it
$builder->add(
$builder->create('user', 'text')
->addModelTransformer($transformer)
);
Note that with a few changes you can get it to work by providing the username rather than the id.

Symfony2 DQL on Fos Userbundle entity

I'm implementing a search on a website and for simplicity i've decided to create a class that does the hard work.
Basically my class takes the EntityManager and the Entities in which i want to search and creates the DQL and executes the query. For normal entities this works totally fine but when i pass the User entity (Extended from fos user bundle entity) i get this error :
[Semantical Error] line 0, col 139 near 'last_login LIKE': Error: Class Soundmerger\UserBundle\Entity\User has no field or association named last_login
The dql query generated seems fine and as it works for the other entities i doubt it comes form there.
Here is my Search class :
use Doctrine\Common\Util\Debug;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query;
class Search {
private $em;
private $searchables;
public function __construct(EntityManager $em, ArrayCollection $searchables){
$this->em = $em;
$this->searchables = $searchables;
}
public function search($query){
$words = explode("+", $query);
$qb = array();
$results = array();
foreach($this->searchables as $qNumber => $searchable){
$qb[$qNumber] = "SELECT s FROM $searchable s ";
$columns = $this->em->getClassMetadata($searchable)->getColumnNames();
foreach($words as $i => $word){
foreach($columns as $k => $column){
$string = "s.$column LIKE '%$word%'";
if($i == 0 && $k == 0){
$qb[$qNumber] .= "WHERE $string";
} else {
$qb[$qNumber] .= "OR $string";
}
}
}
$res[] = $this->em->createQuery($qb[$qNumber])->getResult(Query::HYDRATE_SIMPLEOBJECT);
}
return $this->formatSearch($res);
}
private function formatSearch($results){
$formatedResult = array();
foreach($results as $k => $result){
if(!empty($result)){
$formatedResult[$k]["type"] = get_class($result[0]);
$formatedResult[$k]["data"] = $result[0];
}
}
return $formatedResult;
}
}
And my Controller for the search :
/**
* #Route("/search/{query}")
* #Template()
*/
public function indexAction($query)
{
$em = $this->getDoctrine()->getManager();
$searchables = new ArrayCollection(
array(
"SoundmergerUserBundle:Professional",
"SoundmergerFaqBundle:Faq",
"SoundmergerUserBundle:User",
));
$search = new Search($em, $searchables);
return array('search' => $search->search($query));
}
And finally my user entity :
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
* #AttributeOverrides({
* #AttributeOverride(name="emailCanonical",
* column=#ORM\Column(
* name = "emailCanonical",
* type = "string",
* length = 255,
* nullable = true
* )
* ),
* #AttributeOverride(name="email",
* column=#ORM\Column(
* name = "email",
* type = "string",
* length = 255,
* nullable = true
* )
* ),
* #AttributeOverride(name="username",
* column=#ORM\Column(
* name = "username",
* type = "string",
* length = 255,
* unique = false
* )
* ),
* #AttributeOverride(name="usernameCanonical",
* column=#ORM\Column(
* name = "usernameCanonical",
* type = "string",
* length = 255,
* unique = false
* )
* ),
* })
*/
class User extends BaseUser
{
const STRUCTURE_SOLO = "solo";
const STRUCTURE_GROUP = "group";
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", nullable=true)
* #var string
*/
protected $nomProfile = null;
/**
* #ORM\Column(type="text", nullable=true)
* #var string
*/
protected $description = null;
/**
* #ORM\Column(type="string", nullable=true)
* #var string
*/
protected $type = null;
/**
* #ORM\Column(type="string")
* #var string
*/
protected $structure = self::STRUCTURE_SOLO;
/**
* #ORM\Column(type="string", nullable=true)
* #var string
*/
protected $tel = null;
/**
* #ORM\Column(type="string", nullable=true)
* #var string
*/
protected $site = null;
/**
* #ORM\Column(type="boolean")
* #var bool
*/
protected $firstLogin = true;
/**
* #ORM\OneToOne(targetEntity="Soundmerger\MainBundle\Entity\Address", cascade={"persist"})
*/
protected $address;
/**
* #ORM\OneToMany(targetEntity="Soundmerger\MainBundle\Entity\Style", mappedBy="user", cascade={"persist"})
*/
protected $styles;
/**
* #ORM\OneToMany(targetEntity="Soundmerger\UserBundle\Entity\Member", mappedBy="user")
* #ORM\JoinColumn(nullable=true)
*/
protected $members;
/** #ORM\Column(name="discogs_id", type="string", length=255, nullable=true) */
protected $discogs_id;
/** #ORM\Column(name="discogs_access_token", type="string", length=255, nullable=true) */
protected $discogs_access_token;
public function __construct()
{
parent::__construct();
$this->members = new ArrayCollection();
$this->styles = new ArrayCollection();
}
/**
* Get id
* #return string
*/
public function getId()
{
return $this->id;
}
/**
* Get NomProfile
* #return string
*/
public function getNomProfile()
{
return $this->nomProfile;
}
/**
* Get type
* #return string
*/
public function getType()
{
return $this->type;
}
/**
* Get structure
* #return string
*/
public function getStructure()
{
return $this->structure;
}
/**
* Get tel
* #return string
*/
public function getTel()
{
return $this->tel;
}
/**
* Get site
* #return string
*/
public function getSite()
{
return $this->site;
}
/**
* Get description
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set nomProfile
* #param string $nomProfile
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setNomProfile($nomProfile)
{
$this->nomProfile = $nomProfile;
return $this;
}
/**
* Set type
* #param string $type
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Set structure
* #param string $structure
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setStructure($structure)
{
if (!in_array($structure, array(self::STRUCTURE_SOLO, self::STRUCTURE_GROUP))) {
throw new \InvalidArgumentException("Invalid structure");
}
$this->structure = $structure;
return $this;
}
/**
* Set tel
* #param string $tel
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setTel($tel)
{
$this->tel = $tel;
return $this;
}
/**
* Set site
* #param string $site
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setSite($site)
{
$this->site = $site;
return $this;
}
/**
* Set description
* #param type $description
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Set the first login
* #param bool $firstLogin
* #return \Soundmerger\UserBundle\Entity\Utilisateur
*/
public function setFirstLogin($firstLogin)
{
$this->firstLogin = $firstLogin;
return $this;
}
/**
* Is it the first login
* #return bool returns true if its the first login, false otherwise
*/
public function isFirstLogin()
{
return $this->firstLogin;
}
/**
* Set address
*
* #param Address $address
* #return $this
*/
public function setAddress(Address $address)
{
$this->address = $address;
return $this;
}
/**
* Get adress
*
* #return mixed
*/
public function getAddress()
{
return $this->address;
}
/**
* #return Style
*/
public function getStyles()
{
return $this->styles;
}
/**
* #param Style $style
* #return $this
*/
public function addStyle(Style $style)
{
if (!$this->styles->contains($style)) {
$style->setUser($this);
$this->styles->add($style);
}
return $this;
}
public function setStyles(PersistentCollection $styles)
{
foreach ($styles as $style) {
$this->addStyle($style);
}
}
/**
* #return ArrayCollection
*/
public function getMembers()
{
return $this->members;
}
/**
* #param Member $members
*/
public function addMember(Member $member)
{
if (!$this->members->contains($member)) {
$this->members->add($member);
}
return $this;
}
public function setDiscogsId($discogs_id)
{
$this->discogs_id = $discogs_id;
return $this;
}
public function getDiscogsId()
{
return $this->discogs_id;
}
public function setDiscogsAccessToken($discogs_access_token)
{
$this->discogs_access_token = $discogs_access_token;
return $this;
}
public function getDiscogsAccessToken()
{
return $this->discogs_access_token;
}
public function isRegisteredWithDiscogs(){
return $this->discogs_id != null;
}
}
Any ideas on why this is only happening with the user entity (it must be due to the inheritance but i can't seem to find a way round it)
btw : its a university project so the idea of using an external bundle for the search is not really possible.
Thanks for any help
Dan

UniqueEntity on fosuserbundle field does not work

In my class I've got a UniqueEntity limitation on the "user" field (originally on the combination of "user" and "name"), which is derived from the fosuserbundle, if I put the constraint on "name" for example the constraint does its job and I get an error saying it's not unique. This does not happen on the user field however, I get no error and the entity is added to my database. Could someone point out the mistake I made?
namespace CB\DefaultBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* CustomList
*
* #ORM\Table()
* #ORM\Entity
* #UniqueEntity("user")
*/
class CustomList
{
/**
* #var integer
*
* #ORM\Column(name="Id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=true)
*/
private $description;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="customlists")
* #ORM\JoinColumn(name="user_id", referencedColumnName="Id")
*/
private $user;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="CB\DefaultBundle\Entity\Site", inversedBy="customlists")
* #ORM\JoinTable(name="customlist_site",
* joinColumns={
* #ORM\JoinColumn(name="customlist_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="site_id", referencedColumnName="Id")
* }
* )
*/
private $sites;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return CustomList
*/
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 CustomList
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set category
*
* #param \CB\DefaultBundle\Entity\Category $category
* #return CustomList
*/
public function setCategory(\CB\DefaultBundle\Entity\Category $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \CB\DefaultBundle\Entity\Category
*/
public function getCategory()
{
return $this->category;
}
/**
* Set user
*
* #param \CB\DefaultBundle\Entity\User $user
* #return CustomList
*/
public function setUser(\CB\DefaultBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \CB\DefaultBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Constructor
*/
public function __construct()
{
$this->sites = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add sites
*
* #param \CB\DefaultBundle\Entity\Site $sites
* #return CustomList
*/
public function addSite(\CB\DefaultBundle\Entity\Site $sites)
{
$this->sites[] = $sites;
return $this;
}
/**
* Remove sites
*
* #param \CB\DefaultBundle\Entity\Site $sites
*/
public function removeSite(\CB\DefaultBundle\Entity\Site $sites)
{
$this->sites->removeElement($sites);
}
/**
* Get sites
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSites()
{
return $this->sites;
}
}
Ok, I found my error, It was in my controller logic:
...
$list = new CustomList();
$form = $this->createForm(new CustomListType(), $list);
$form->submit($request);
$list = $form->getData();
$validator = $this->get('validator');
$errors = $validator->validate($list);
var_dump((string) $errors);
if ($form->isValid()){
$em = $this->getDoctrine()->getManager();
//set current user as user-value of this list
$list->setUser($this->getUser());
$em->persist($list);
$em->flush();
//prepare the response, e.g.
$response = array("code" => 100, "success" => true);
//you can return result as JSON , remember to 'use' Response!
return new Response(json_encode($response));
...
As you can see I set the user AFTER the form has been validated, meaning it would always validate the null values, as seen in the documentation here: UniqueEntity the default value of ignoreNull is true, meaning it would always pass the test.
Moving the $list->setUser($this->getUser()); line before my validation of the form fixed this problem!

Missing an assigned ID for field

I'm lost in a complexe relation (for me). I've a entity project for an entity client and you can attach users to a project. When i try to add a project without users, no problem. But, when i try to add a project and users Sf2 display this error :
Entity of type Intranet\IntranetBundle\Entity\ProjectUser is missing an assigned ID for field 'project'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
I'm understand it's angry because the project_id is null. But i don't know why it's null.
My Project.php
namespace Intranet\IntranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Project
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Intranet\IntranetBundle\Entity\ProjectRepository")
*/
class Project
{
/**
* #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(
* message = "The field cannot be empty"
* )
*/
private $name;
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(length=255, unique=true)
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="contact_client", type="text", nullable=true)
*/
private $contactClient;
/**
* #var string
*
* #ORM\Column(name="technologies", type="string", length=255, nullable=true)
*/
private $technologies;
/**
* #var string
*
* #ORM\Column(name="languages", type="string", length=255, nullable=true)
*/
private $languages;
/**
* #var string
*
* #ORM\Column(name="extern", type="text", nullable=true)
*/
private $extern;
/**
* #var string
*
* #ORM\Column(name="url_prod", type="string", length=255, nullable=true)
*/
private $urlProd;
/**
* #var string
*
* #ORM\Column(name="url_staging", type="text", nullable=true)
*/
private $urlStaging;
/**
* #var string
*
* #ORM\Column(name="url_dev", type="text", nullable=true)
*/
private $urlDev;
/**
* #var string
*
* #ORM\Column(name="hosting_company", type="string", length=255, nullable=true)
*/
private $hostingCompany;
/**
* #var string
*
* #ORM\Column(name="hosting_type", type="string", length=255, nullable=true)
*/
private $hostingType;
/**
* #var string
*
* #ORM\Column(name="hosting_manager", type="text", nullable=true)
*/
private $hostingManager;
/**
* #var string
*
* #ORM\Column(name="ssh", type="text", nullable=true)
*/
private $ssh;
/**
* #var string
*
* #ORM\Column(name="ftp", type="text", nullable=true)
*/
private $ftp;
/**
* #var string
*
* #ORM\Column(name="db", type="text", nullable=true)
*/
private $db;
/**
* #var string
*
* #ORM\Column(name="emails", type="text", nullable=true)
*/
private $emails;
/**
* #var string
*
* #ORM\Column(name="cms", type="text", nullable=true)
*/
private $cms;
/**
* #var string
*
* #ORM\Column(name="web_services", type="text", nullable=true)
*/
private $webServices;
/**
* #var string
*
* #ORM\Column(name="comment", type="text", nullable=true)
*/
private $comment;
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Client", inversedBy="projects")
* #ORM\JoinColumn(nullable=false)
*/
private $client;
/**
* #ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="project", cascade={"persist"})
*/
private $projectUsers;
public function __construct()
{
$this->projectUsers = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Project
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set slug
*
* #param string $slug
* #return Client
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set contactClient
*
* #param string $contactClient
* #return Project
*/
public function setContactClient($contactClient)
{
$this->contactClient = $contactClient;
return $this;
}
/**
* Get contactClient
*
* #return string
*/
public function getContactClient()
{
return $this->contactClient;
}
/**
* Set technologies
*
* #param string $technologies
* #return Project
*/
public function setTechnologies($technologies)
{
$this->technologies = $technologies;
return $this;
}
/**
* Get technologies
*
* #return string
*/
public function getTechnologies()
{
return $this->technologies;
}
/**
* Set languages
*
* #param string $languages
* #return Project
*/
public function setLanguages($languages)
{
$this->languages = $languages;
return $this;
}
/**
* Get languages
*
* #return string
*/
public function getLanguages()
{
return $this->languages;
}
/**
* Set extern
*
* #param string $extern
* #return Project
*/
public function setExtern($extern)
{
$this->extern = $extern;
return $this;
}
/**
* Get extern
*
* #return string
*/
public function getExtern()
{
return $this->extern;
}
/**
* Set urlProd
*
* #param string $urlProd
* #return Project
*/
public function setUrlProd($urlProd)
{
$this->urlProd = $urlProd;
return $this;
}
/**
* Get urlProd
*
* #return string
*/
public function getUrlProd()
{
return $this->urlProd;
}
/**
* Set urlStaging
*
* #param string $urlStaging
* #return Project
*/
public function setUrlStaging($urlStaging)
{
$this->urlStaging = $urlStaging;
return $this;
}
/**
* Get urlStaging
*
* #return string
*/
public function getUrlStaging()
{
return $this->urlStaging;
}
/**
* Set urlDev
*
* #param string $urlDev
* #return Project
*/
public function setUrlDev($urlDev)
{
$this->urlDev = $urlDev;
return $this;
}
/**
* Get urlDev
*
* #return string
*/
public function getUrlDev()
{
return $this->urlDev;
}
/**
* Set hostingCompany
*
* #param string $hostingCompany
* #return Project
*/
public function setHostingCompany($hostingCompany)
{
$this->hostingCompany = $hostingCompany;
return $this;
}
/**
* Get hostingCompany
*
* #return string
*/
public function getHostingCompany()
{
return $this->hostingCompany;
}
/**
* Set hostingType
*
* #param string $hostingType
* #return Project
*/
public function setHostingType($hostingType)
{
$this->hostingType = $hostingType;
return $this;
}
/**
* Get hostingType
*
* #return string
*/
public function getHostingType()
{
return $this->hostingType;
}
/**
* Set hostingManager
*
* #param string $hostingManager
* #return Project
*/
public function setHostingManager($hostingManager)
{
$this->hostingManager = $hostingManager;
return $this;
}
/**
* Get hostingManager
*
* #return string
*/
public function getHostingManager()
{
return $this->hostingManager;
}
/**
* Set ssh
*
* #param string $ssh
* #return Project
*/
public function setSsh($ssh)
{
$this->ssh = $ssh;
return $this;
}
/**
* Get ssh
*
* #return string
*/
public function getSsh()
{
return $this->ssh;
}
/**
* Set ftp
*
* #param string $ftp
* #return Project
*/
public function setFtp($ftp)
{
$this->ftp = $ftp;
return $this;
}
/**
* Get ftp
*
* #return string
*/
public function getFtp()
{
return $this->ftp;
}
/**
* Set db
*
* #param string $db
* #return Project
*/
public function setDb($db)
{
$this->db = $db;
return $this;
}
/**
* Get db
*
* #return string
*/
public function getDb()
{
return $this->db;
}
/**
* Set emails
*
* #param string $emails
* #return Project
*/
public function setEmails($emails)
{
$this->emails = $emails;
return $this;
}
/**
* Get emails
*
* #return string
*/
public function getEmails()
{
return $this->emails;
}
/**
* Set cms
*
* #param string $cms
* #return Project
*/
public function setCms($cms)
{
$this->cms = $cms;
return $this;
}
/**
* Get cms
*
* #return string
*/
public function getCms()
{
return $this->cms;
}
/**
* Set webServices
*
* #param string $webServices
* #return Project
*/
public function setWebServices($webServices)
{
$this->webServices = $webServices;
return $this;
}
/**
* Get webServices
*
* #return string
*/
public function getWebServices()
{
return $this->webServices;
}
/**
* Set comment
*
* #param string $comment
* #return Project
*/
public function setComment($comment)
{
$this->comment = $comment;
return $this;
}
/**
* Get comment
*
* #return string
*/
public function getComment()
{
return $this->comment;
}
/**
* Set client
*
* #param \Intranet\IntranetBundle\Entity\Client $client
* #return Project
*/
public function setClient(\Intranet\IntranetBundle\Entity\Client $client)
{
$this->client = $client;
return $this;
}
/**
* Get client
*
* #return \Intranet\IntranetBundle\Entity\Client
*/
public function getClient()
{
return $this->client;
}
public function addProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
{
$this->projectUsers[] = $projectUser;
}
public function removeProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
{
$this->projectUsers->removeElement($projectUser);
}
public function getProjectUsers()
{
return $this->projectUsers;
}
}
My ProjectUser.php
namespace Intranet\IntranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class ProjectUser
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
*/
private $project;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Intranet\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Column(name="profil", type="smallint")
*/
private $profil;
public function setProject(\Intranet\IntranetBundle\Entity\Project $project)
{
$project->addProjectUser($this);
$this->project = $project;
}
public function getProject()
{
return $this->project;
}
public function setUser(\Intranet\UserBundle\Entity\User $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function setProfil($profil)
{
$this->profil = $profil;
}
public function getProfil()
{
return $this->profil;
}
}
profil = smallint for the job of the user (1=manager, 2=designer, ...)
My ProjectController (addAction)
public function addAction()
{
$project = new Project;
$form = $this->createForm(new ProjectType, $project);
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($project);
$em->flush();
foreach ($form->get('projectUsers')->getData() as $u) {
$u->setProject($project);
$em->persist($u);
}
$em->flush();
$this->get('session')->getFlashBag()->add('success', 'The project : '. $project->getName() .' has been added');
return $this->redirect($this->generateUrl('clients_list'));
}
}
return $this->render('IntranetIntranetBundle:Project:add_project.html.twig', array(
'form' => $form->createView()
));
}
Thanks for your help
Well, first of all, you shouldn't specify #ORM\Id annotation on every foreign key in your ProjectUser entity - it is for primary keys.
Then you should declare column join on foreign key fields:
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
* #ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
private $project;
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\User", inversedBy="projects")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
You also should have a field like
class User
{
// ...
/**
* #ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="user")
*/
private $projects;
// ...
}
Finally, to add user to project, I suggest you embed a ProjectUserType form with user selection into ProjectType form. In your controller, you can have something like
public function addAction()
{
$project = new Project;
$projectUser = new ProjectUser();
$projectUser->setProject($project);
$project->addProjectUser($projectUser);
$form = $this->createForm(new ProjectType, $project);
// ...
And in form ProjectUserType
class ProjectUserType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('user', 'entity', array(
'class' => 'Intranet:IntranetBundle:User'
));
// ...
Hope this helps at least a little bit.
When you code : $em->persist($project);
$project is equal to $project = new Project; (don't you have forget '()' ?)
Actually the $projet is empty... To do this, I think you forget to code :
$project = $form->getData();

Resources