How to write request for loading all users from DB by user role?
I am using three tables (users, role and user_role) with many-to-many relations.
If you can help mе to write function loadUsersByRole() in UserRepository i I would be very grateful.
Entity\User
namespace Kombinator\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Kombinator\UserBundle\Entity\User
*
* #ORM\Table(name="kombinator_users")
* #ORM\Entity(repositoryClass="Kombinator\UserBundle\Entity\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\ManyToOne(targetEntity="Company")
* #ORM\JoinColumn(name="company", referencedColumnName="id")
*/
protected $company;
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*
*/
private $roles;
public function __construct()
{
$this->roles = new ArrayCollection();
}
public function getRoles()
{
return $this->roles->toArray();
}
public function getRole()
{
$roles=$this->roles->toArray();
if(isset($roles[0])){return $roles[0];}
else{return NULL;}
}
...
UserRepository
namespace Kombinator\UserBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Kombinator\UserBundle\Controller\Paginator;
use Kombinator\UserBundle\Entity\Filter;
use Kombinator\UserBundle\Entity\Role;
/**
* UserRepository
*/
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$q = $this
->createQueryBuilder('u')
->select('u, r')
->leftJoin('u.roles', 'r')
->where('u.email = :email AND u.status = 1')
->setParameter('email', $username)
->getQuery();
try {
$user = $q->getSingleResult();
} catch (NoResultException $e) {
$message = sprintf('Unable to find an active ... by "%s".',$username);
throw new UsernameNotFoundException($message, 0, $e);
}
return $user;
}
public function findAllActiveJoinedToCompany($company)
{
$query = $this->getEntityManager()
->createQuery('
SELECT p, c FROM KombinatorUserBundle:User p
JOIN p.company c WHERE p.company='.$company);
try {
return $query;
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
Entity\Role
namespace Kombinator\UserBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="kombinator_role")
* #ORM\Entity()
*/
class Role implements RoleInterface
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=30)
*/
private $name;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* #see RoleInterface
*/
public function getRole()
{
return $this->role;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Role
*/
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 Role
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Add users
*
* #param \Kombinator\UserBundle\Entity\User $users
* #return Role
*/
public function addUser(\Kombinator\UserBundle\Entity\User $users)
{
$this->users[] = $users;
return $this;
}
/**
* Remove users
*
* #param \Kombinator\UserBundle\Entity\User $users
*/
public function removeUser(\Kombinator\UserBundle\Entity\User $users)
{
$this->users->removeElement($users);
}
/**
* Get users
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
}
RoleRepository
namespace Kombinator\UserBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
* RoleRepository
*/
class RoleRepository extends EntityRepository
{
public function findAll()
{
$query = $this->getEntityManager()
->createQuery('
SELECT p FROM KombinatorUserBundle:Role p
ORDER BY p.id'
);
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
}
When many-to-many relationship is involved you should use MEMBER OF clause in your query:
public function loadUsersByRole($roleId)
{
$q = $this
->createQueryBuilder('u')
->select('u, r')
->leftJoin('u.roles', 'r')
->where(':roleId MEMBER OF u.roles AND u.status = 1')
->setParameter('roleId', $roleId)
->getQuery();
return $q->getResult();
}
Related
Im trying to insert into my database (Oracle 12c) table a new entry but im failing to do that
The following is my entity:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Divisions
*
* #ORM\Table(name="DIVISIONS")
* #ORM\Entity
*/
class Divisions
{
/**
* #var int
*
* #ORM\Column(name="DIVISIONID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="DIVISIONS_DIVISIONID_seq", allocationSize=1, initialValue=1)
*/
public $divisionid = '"SPECIFICATIONS"."ISEQ$$_79111".nextval';
/**
* #var string|null
*
* #ORM\Column(name="DIVISIONNAME", type="string", length=500, nullable=true)
*/
public $divisionname;
/**
* #var int|null
*
* #ORM\Column(name="SORTORDER", type="integer", nullable=true, options={"default"="1"})
*/
public $sortorder = '1';
/**
* #var int|null
*
* #ORM\Column(name="ISDELETED", type="integer", nullable=true)
*/
public $isdeleted = '0';
public function getDivisionid(): ?int
{
return $this->divisionid;
}
public function getDivisionname(): ?string
{
return $this->divisionname;
}
public function setDivisionname(?string $divisionname): self
{
$this->divisionname = $divisionname;
return $this;
}
public function getSortorder(): ?int
{
return $this->sortorder;
}
public function setSortorder(?int $sortorder): self
{
$this->sortorder = $sortorder;
return $this;
}
public function getIsdeleted(): ?int
{
return $this->isdeleted;
}
public function setIsdeleted(?int $isdeleted): self
{
$this->isdeleted = $isdeleted;
return $this;
}
}
And here is my controller that is trying to "POST" and add a new Division
<?php
namespace App\Controller;
use App\Entity\Divisions;
use App\Form\DivisionsType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
/**
* #Route("api/divisions")
*/
class DivisionsController extends AbstractController
{
/**
* #Route("", name="divisions_add", methods={"POST"})
*/
public function addDivisions(Request $request)
{
$em = $this->getDoctrine()->getManager();
$division = new Divisions();
$division->setDivisionname('TestDiv');
$em->persist($division);
$em->flush();
return new Response(
Response::HTTP_OK
);
}
}
when i try to call this the following Error message will appear:
An exception occurred while executing 'INSERT INTO DIVISIONS (DIVISIONID, DIVISIONNAME, SORTORDER, ISDELETED) VALUES (?, ?, ?, ?)' with params [16, "TestDiv", "1", "0"]:
ORA-32795: cannot insert into a generated always identity column
For some reason no matter what i try the DivisionID column will be called.. is there a way to insert without calling some certain columns?
Or is there a way to send it as 'INSERT INTO DIVISIONS (DIVISIONNAME, SORTORDER, ISDELETED) VALUES (?, ?, ?)' with params ["TestDiv", "1", "0"]'
PS: Entity is auto generated from database
If anybody wants more info ill happily provide
Ok so if anybody reaches this point and is still stuck i find kind of a work around:
I changed my Entity to look like that:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Divisions
*
* #ORM\Table(name="DIVISIONS")
* #ORM\Entity
*/
class Divisions
{
/**
* #var int
*
* #ORM\Column(name="DIVISIONID", type="integer", nullable=false)
* #ORM\Id
*/
public $divisionid;
/**
* #var string|null
*
* #ORM\Column(name="DIVISIONNAME", type="string", length=500, nullable=true)
*/
public $divisionname;
/**
* #var int|null
*
* #ORM\Column(name="SORTORDER", type="integer", nullable=true, options={"default"="1"})
*/
public $sortorder = '1';
/**
* #var int|null
*
* #ORM\Column(name="ISDELETED", type="integer", nullable=true)
*/
public $isdeleted = '0';
public function getDivisionid(): ?int
{
return $this->divisionid;
}
public function getDivisionname(): ?string
{
return $this->divisionname;
}
public function setDivisionname(?string $divisionname): self
{
$this->divisionname = $divisionname;
return $this;
}
public function getSortorder(): ?int
{
return $this->sortorder;
}
public function setSortorder(?int $sortorder): self
{
$this->sortorder = $sortorder;
return $this;
}
public function getIsdeleted(): ?int
{
return $this->isdeleted;
}
public function setIsdeleted(?int $isdeleted): self
{
$this->isdeleted = $isdeleted;
return $this;
}
}
Then in the Controller i added the following function:
private function getMaxDivisionIdNumber() {
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT MAX(u.divisionid) FROM App\Entity\Divisions u');
$res = $query->getResult();
return $res[0][1];
}
Now this function is used to get the Max id number.. so my controller would look something like that:
<?php
namespace App\Controller;
use App\Entity\Divisions;
use App\Form\DivisionsType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
/**
* #Route("api/divisions")
*/
class DivisionsController extends AbstractController
{
/**
* #Route("", name="divisions_add", methods={"POST"})
*/
public function addDivisions(Request $request)
{
$em = $this->getDoctrine()->getManager();
$content = $request->getContent();
$content = json_decode($content);
$division = new Divisions();
foreach ($content as $key => $value) {
$division->$key = $value;
}
$maxId = (int) $this->getMaxDivisionIdNumber();
$division->divisionid = $maxId + 1;
$em->persist($division);
$em->flush();
return new Response(
Response::HTTP_OK
);
}
private function getMaxDivisionIdNumber() {
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT MAX(u.divisionid) FROM App\Entity\Divisions u');
$res = $query->getResult();
return $res[0][1];
}
}
A User has many Games.
A Game can Belong to many Users.
I have a form with a list of games, I want the list of Games to be added to the current logged User.
When I submit the form nothing happens, I want at least 1 record to be added to users_games:
Update:
Added User entity
FormType addGameToUserType:
namespace AppBundle\Form;
use AppBundle\Entity\Game;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class addGameToUserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('game', EntityType::class, [
'class' => 'AppBundle:Game',
'choice_label' => function ($game) {
return $game->getName();
},
'multiple' => true,
'expanded' => false,
]);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getBlockPrefix()
{
return 'app_bundleadd_game_to_user';
}
}
UserController addGameAction:
/**
* Adds game(s) to current user.
*
* #Route("user/game/add", name="game_add")
* #Method({"GET", "POST"})
*/
public function addGameAction(Request $request)
{
/** #var $form */
$form = $this->createForm('AppBundle\Form\addGameToUserType');
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
echo $form->get('game')->getData();
$em = $this->getDoctrine()->getManager();
/** #var $game */
$game = new Game();
$game->getId();
/** #var User $userObject */
$userObject = $this->getUser();
$user = $em->getRepository('AppBundle:User')
->find(['id' => $userObject->getId()]);
$game->addGameUser($user);
$em->persist($user);
$em->flush();
}
return $this->render('user/addGame.html.twig', array(
'form' => $form->createView()
));
}
Game entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Game
*
* #ORM\Table(name="game")
* #ORM\Entity(repositoryClass="AppBundle\Repository\GameRepository")
*/
class Game
{
/**
* #ORM\OneToMany(targetEntity="PlayLog", mappedBy="game")
* #ORM\OrderBy({"date" = "DESC"})
*
*/
private $playlogs;
private $users;
/**
* #return ArrayCollection
*/
public function getUsers()
{
return $this->users;
}
/**
* #param ArrayCollection $users
*/
public function setUsers($users)
{
$this->users = $users;
}
// private $categories;
public function __construct()
{
$this->playlogs = new ArrayCollection();
$this->users = new ArrayCollection();
}
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #Assert\Length(
* min = "3",
* max = "100"
* )
* #ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Game
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #return mixed
*/
public function getPlaylogs()
{
return $this->playlogs;
}
/**
* #param mixed $playlogs
*/
public function setPlaylogs($playlogs)
{
$this->playlogs = $playlogs;
}
public function addPlayLog(PlayLog $playlog)
{
$this->playlog->add($playlog);
$playlog->setPlayLogs($this);
}
public function addGameUser(User $user){
$this->users[] = $user;
}
}
User entity:
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\ManyToMany(targetEntity="Game")
*
* #ORM\JoinTable(name="users_games",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")}
* )
*/
private $games;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PlayLog", mappedBy="user")
*
*/
private $playlogs;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
public function __construct()
{
$this->games = new ArrayCollection();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #return mixed
*/
public function getGames()
{
return $this->games;
}
/**
* #param mixed $games
*/
public function setGames($games)
{
$this->games = $games;
}
public function addGame(Game $game)
{
// $this->games->add($game);
$this->games[] = $game;
return $this;
}
public function removeGame(Game $game)
{
$this->games->removeElement($game);
}
/**
* #return mixed
*/
public function getPlaylogs()
{
return $this->playlogs;
}
/**
* #param mixed $playlogs
*/
public function setPlaylogs($playlogs)
{
$this->playlogs = $playlogs;
}
public function addPlayLog(PlayLog $playlog)
{
$this->playlog->add($playlog);
$playlog->setPlayLogs($this);
}
}
Here is my Insert Query, how can I tell that, created_at(current time-stamp), is_active(default 1) set in the mysql db structure needs to be taken.
When I omit the $question->setCreatedAt($this->createdAt); in the insert operation it shows me an Integrity constraint violation, do you know what is the issue?
In the Questions table:
question:
id
question
created_by
created_at
modified_by
modified_at
is_Active
Entity:
<?php
namespace Library\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Base class for all the Entities
* This class maps id, active, created and modified columns
*
* #author
*/
/**
* #ORM\MappedSuperclass
*/
class BaseEntity {
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id", type="integer")
* #var integer
*/
protected $id;
/**
* #ORM\Column(name="is_active", type="boolean")
* #var boolean
*/
protected $active;
/**
* #ORM\Column(name="created_at", type="datetime")
* #var datetime
*/
protected $createdAt;
/**
* #ORM\Column(name="created_by", type="integer", nullable=true)
* #var integer
*/
protected $createdBy;
/**
* #ORM\Column(name="modified_at", type="datetime")
* #var datetime
*/
protected $modifiedAt;
/**
* #ORM\Column(name="modified_by", type="integer")
* #var integer
*/
protected $modifiedBy;
public function getId() {
return $this->id;
}
public function getActive() {
return $this->active;
}
public function getCreatedAt() {
return $this->createdAt;
}
public function getCreatedBy() {
return $this->createdBy;
}
public function getModifiedAt() {
return $this->modifiedAt;
}
public function getModifiedBy() {
return $this->modifiedBy;
}
public function setId($id) {
$this->id = $id;
}
public function setActive($active) {
$this->active = $active;
}
public function setCreatedAt($createdAt) {
$this->createdAt = $createdAt;
}
public function setCreatedBy($createdBy) {
$this->createdBy = $createdBy;
}
public function setModifiedAt($modifiedAt) {
$this->modifiedAt = $modifiedAt;
}
public function setModifiedBy($modifiedBy) {
$this->modifiedBy = $modifiedBy;
}
}
This is my Question Entity:
<?php
namespace Survey\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Library\Entity\BaseEntity;
use Survey\Entity\Survey;
/**
* Description of Survey Questions
*
* #author Mubarak
*/
/**
* #ORM\Entity
* #ORM\Table(name="survey_questions")
*/
class Question extends BaseEntity{
/**
* #ORM\Column(name="question", type="string")
* #var string
*/
protected $question;
/**
* #ORM\ManyToOne(targetEntity="Survey\Entity\Survey", inversedBy="questions")
* #ORM\JoinColumn(name="survey_id", referencedColumnName="id")
*/
private $surveys;
public function getQuestion() {
return $this->question;
}
public function setQuestion($question) {
$this->question = $question;
}
public function getSurveys() {
return $this->surveys;
}
// public function setSurveys(ArrayCollection $survey) {
public function setSurveys(Survey $surveys = null) {
$this->surveys = $surveys;
}
// public function __toString() {
// return __CLASS__ . ": [id: {$this->id}, name: {$this->name}]";
// }
}
Here is my insert Operation:
public function insertQuestion($userId, $survey, $questionArr) {
try{
$question = new Question();
$question->setQuestion($questionArr['question']);
$question->setSurveys($survey);
$question->setActive(1);
$question->setCreatedBy($userId);
$question->setCreatedAt($this->createdAt);
$question->setModifiedBy($userId);
$question->setModifiedAt($this->modifiedAt);
$this->entityManager->persist($question);
$this->entityManager->flush();
return $question;
}catch(Exception $ex){
throw new Exception("Couldnt insert the question");
}
}
This is Ok, its working properly, but i dont want to insert the Created_at, modified_at
public function insertQuestion($userId, $survey, $questionArr) {
try{
$question = new Question();
$question->setQuestion($questionArr['question']);
$question->setSurveys($survey);
$question->setActive(1);
$question->setCreatedBy($userId);
$question->setModifiedBy($userId);
$this->entityManager->persist($question);
$this->entityManager->flush();
return $question;
}catch(Exception $ex){
throw new Exception("Couldnt insert the question");
}
}
If you want to set default values it is best to set them in your object model where possible.
/**
* #ORM\Column(name="is_active", type="boolean")
* #var boolean
*/
protected $active = true;
For time-stamps though it is a bit of a different story...
I would suggest to take a look at the Gedmo doctrine extensions library which includes solutions for createdAt and other common columns for your model. No need to reinvent the wheel... .
So i want to display all the courses within my database in a drop down form. a user who is logged in then select one of the drop downs and it would store the users ID and the course ID into the database. How would i go about doing this?
Here's my course entity course.php
<?php
// src/Simple/SimpleBundle/Entity/Course.php
namespace Simple\ProfileBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="course")
*/
class Course
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="course", type="string", length=255)
*/
protected $course;
public function __construct()
{
$this->users = new ArrayCollection();
}
public function setCourse($course)
{
$this->course = $course;
}
public function getCourse()
{
return $this->course;
}
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
ChooseCourseType.php my form
<?php
// src/Simple/ProfileBundle/Controller/ChooseCourseType.php
namespace Simple\ProfileBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ChooseCourseType extends AbstractType
{
private $course;
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('course', 'choice', array(
'choices' => $this->course,
));
$builder->add('Choose Course', 'submit');
}
public function getName()
{
return 'name';
}
public function getCourse()
{
return 'course';
}
}
Coursecontroller.php
function chooseAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new ChooseCourseType(), $CourseType);
$form->handleRequest($request);
if ($form->isValid()) {
$course = $form->getData();
$em->persist($course->getCourse());
$em->flush();
}
return $this->render(
'SimpleProfileBundle:Course:choosecourse.html.twig',
array('form' => $form->createView())
);
}
}
User.php
namespace Simple\ProfileBundle\Entity;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="user", type="string", length=255)
*/
protected $username;
/**
* #ORM\Column(name="password", type="string", length=255)
*/
protected $password;
/**
* #ORM\Column(name="salt", type="string", length=255)
*/
protected $salt;
/**
* #ORM\ManyToMany(targetEntity="Role")
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* #ORM\ManyToMany(targetEntity="Course")
* #ORM\JoinTable(name="user_course",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="course_id",
referencedColumnName="id")}
* )
*/
protected $courses;
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->username;
}
/**
* #inheritDoc
*/
public function getSalt()
{
return '';
}
/**
* #inheritDoc
*/
public function getPassword()
{
return $this->password;
}
/**
* #inheritDoc
*/
public function getRoles()
{
return $this->roles->toArray();
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* Constructor
*/
public function __construct()
{
$this->roles = new \Doctrine\Common\Collections\ArrayCollection();
$this->salt = sha1(uniqid(null, true));
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param string $user
* #return User
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return string
*/
public function getUser()
{
return $this->user;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Add roles
*
* #param \Simple\ProfileBundle\Entity\Role $roles
* #return User
*/
public function addRole(\Simple\ProfileBundle\Entity\Role $roles)
{
$this->roles[] = $roles;
return $this;
}
/**
* Remove roles
*
* #param \Simple\ProfileBundle\Entity\Role $roles
*/
public function removeRole(\Simple\ProfileBundle\Entity\Role $roles)
{
$this->roles->removeElement($roles);
}
/**
* Add roles
*
* #param \Simple\ProfileBundle\Entity\Course $courses
* #return User
*/
public function addCourse(\Simple\ProfileBundle\Entity\Course $courses)
{
$this->course[] = $courses;
return $this;
}
}
What else am i missing i am new to symfony2 and just need some direction.
Cheers
You need to use the entity form type.
Form type
<?php
// src/Simple/ProfileBundle/Controller/ChooseCourseType.php
namespace Simple\ProfileBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ChooseCourseType extends AbstractType {
$builder->add('courses', 'entity', array(
'label' => 'Courses',
'class' => 'SimpleSimpleBundle:Course',
'expanded' => false,
'multiple' => false
))
// ...
Controller
function chooseAction(Request $request) {
$em = $this->getDoctrine()->getManager();
// Replace this with whatever logic you use to find the user
$user = $em->getRepository('SimpleSimpleBundle:User')->findOneBy(
array('id' => 1)
);
$form = $this->createForm(new ChooseCourseType(), $user);
$form->handleRequest($request);
if ($form->isValid()) {
$user = $form->getData();
// Since you've bound this user object to the form and properly
// created a relationship between the course and user entities
// the relationship between course and user will persist here
$em->persist($user);
$em->flush();
}
I have such doctrine entities:
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity(repositoryClass="App\Repository\Page")
* #Table(name="page")
*/
class Page
{
/**
* #Id #Column(type="integer", name="p_id")
* #GeneratedValue
*/
private $p_id;
/** #Column(type="string", name="p_title") */
private $p_title;
/** #Column(type="datetime", name="p_created") */
private $p_created_at;
/** #Column(type="datetime", name="p_updated_at") */
private $p_updated_at;
/** #Column(type="text", name="p_abstract") */
private $p_abstract;
/** #Column(type="text", name="p_fulltext", nullable=false) */
private $p_fulltext;
/** #Column(type="string", name="p_author", nullable=true) */
private $p_author;
/** #Column(type="string", name="p_url",nullable=true) */
private $p_url;
/** #Column(type="string", name="p_meta_title",nullable=true) */
private $p_meta_title;
/** #Column(type="string", name="p_meta_keywords",nullable=true) */
private $p_meta_keywords;
/** #Column(type="string", name="p_meta_description",nullable=true) */
private $p_meta_description;
/** #Column(type="string", name="p_status") */
private $p_status;
/**
* #ManyToOne(targetEntity="User", inversedBy="pages")
* #JoinColumn(name="p_u_id", referencedColumnName="u_id")
*/
private $user;
/**
* #OneToMany(targetEntity="App\Entity\Page\Media", mappedBy="pages")
* #var \Doctrine\Common\Collections\Collection
*/
protected $pageMedia;
/**
* #OneToMany(targetEntity="App\Entity\Page\Basket", mappedBy="baskets")
* #var \Doctrine\Common\Collections\Collection
*/
protected $pageBasket;
public function __construct()
{
$this->pageMedia = new App\Entity\Page\Media();
$this->medias = new ArrayCollection();
}
public function __get($property)
{
return $this->property;
}
public function __set($property,$value)
{
$this->$property = $value;
}
public function setUser(user $user)
{
$this->user = $user;
}
public function setMedia(media $media)
{
$this->pageMedia->setPageAndMedia($this,$media);
}
/**
* Set Page Values
* #var array $values
*/
public function setPageProperties(array $values)
{
$this->p_updated_at = new \DateTime("now");
$this->p_title = $values['p_title'];
$this->p_abstract = $values['p_abstract'];
$this->p_meta_title = $values['p_meta_title'];
$this->p_meta_keywords = $values['p_meta_keywords'];
$this->p_meta_description = $values['p_meta_description'];
$this->p_url = $values['p_url'];
$this->p_fulltext = $values['p_abstract'];
$this->p_author = '';
$this->p_status = 1;
}
}
?>
<?php
namespace App\Entity\Page;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity
* #Table(name="page_basket")
*/
class Basket
{
/**
* #Id #Column(type="integer", name="pb_id")
* #GeneratedValue
*/
private $pb_id;
/**
* #ManyToOne(targetEntity="App\Entity\Page")
* #JoinColumn(name="pb_p_id", referencedColumnName="p_id")
*/
private $pages;
/**
* #ManyToOne(targetEntity="App\Entity\Basket",inversedBy="pageBasket")
* #JoinColumn(name="pb_b_id", referencedColumnName="b_id")
*/
private $baskets;
public function __construct()
{
$this->baskets = new ArrayCollection();
$this->pages = new ArrayCollection();
}
public function __get($property)
{
return $this->property;
}
public function __set($property,$value)
{
$this->$property = $value;
}
/**
*
*/
public function setPageAnBasket(page $page,basket $basket)
{
$this->pages[] = $page;
$this->baskets[] = $basket;
}
}
?>
And method in repository:
<?php
namespace App\Repository;
use Doctrine\ORM\EntityRepository;
class Page extends EntityRepository
{
/**
* Find pages by basket Id
* #var int $basketId
* #return array $pages[]
*/
public function findPagesByBasket($basketId)
{
$dql = $this->_em->createQueryBuilder();
$dql->select('u')
->from('App\Entity\Page', 'p')
->leftJoin('p.App\Entity\Page\Basket','pb_b_id = p_id')
->andWhere('pb_b_id = :basketId')
->setParameter('basketId', $basketId);
return $dql->getQuery()->getArrayResult();
}
}
But when I ry to run dql all I'm getting:
string '[Semantical Error] line 0, col 67 near 'pb_b_id = p_id': Error: Class App\Entity\Page has no association named App\Entity\Page\Basket'
What I'm doing wrong because I don't want to use many to many relation because I wanna have additional fields in join table.
I needed a good excuse to make myself a simple test case so here it is.
namespace Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity()
* #Table(name="page")
*/
class Page
{
/**
* #Id #Column(type="integer", name="p_id")
* #GeneratedValue
*/
private $id;
/**
* #OneToMany(targetEntity="Entity\PageBasket", mappedBy="page")
*/
protected $pageBaskets;
public function __construct()
{
$this->pageBaskets = new ArrayCollection();
}
public function getId() { return $this->id; }
public function getPageBaskets() { return $this->pageBaskets; }
}
namespace Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity
* #Table(name="page_basket")
*/
class PageBasket
{
/**
* #Id #Column(type="integer", name="pb_id")
* #GeneratedValue
*/
private $id;
/**
* #ManyToOne(targetEntity="Entity\Page")
* #JoinColumn(name="page_id", referencedColumnName="p_id")
*/
private $page;
public function setPage($page)
{
$this->page = $page;
}
public function getId() { return $this->id; }
}
And a working test query
protected function testQuery()
{
$basketId = 1;
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb->addSelect('page');
$qb->addSelect('pageBasket');
$qb->from('\Entity\Page','page');
$qb->leftJoin('page.pageBaskets','pageBasket');
$qb->andWhere($qb->expr()->in('pageBasket.id',$basketId));
$query = $qb->getQuery();
$results = $query->getResult();
$page = $results[0];
$pageBaskets = $page->getPageBaskets();
$pageBasket = $pageBaskets[0];
echo 'Result Count ' . count($results) . "\n";
echo 'Page ID ' . $page->getId() . "\n";
echo 'Page Basket ID ' . $pageBasket->getId() . "\n";
echo $query->getSQL() . "\n";
}
The generated sql look like:
SELECT p0_.p_id AS p_id0, p1_.pb_id AS pb_id1, p1_.page_id AS page_id2
FROM page p0_
LEFT JOIN page_basket p1_ ON p0_.p_id = p1_.page_id
WHERE p1_.pb_id IN (1)