No #QueryParam/#RequestParam configuration for parameter 'username' - symfony

Help me please, i create my own annotations extending fosrestbundle annotation, to have url in this format users?param=...&param2=...
my annotation is as follows:
<?php
namespace REST\UserBundle\Annotations;
use FOS\RestBundle\Controller\Annotations\Param;
use Symfony\Component\HttpFoundation\Request;
/**
* #Annotation
* #Target({"CLASS", "METHOD"})
*/
class CustomParam extends Param
{
/**
* {#inheritdoc}
*/
public function getValue(Request $request, $default = null)
{
return $request->request->has($this->getKey())
? $request->request->get($this->getKey(), $default)
: $request->query->get($this->getKey(), $default);
}
}
my controller is as following:
/**
* Create a User from the submitted data.<br/>
*
* #ApiDoc(
* resource = true,
* description = "Creates a new user from the submitted data.",
* statusCodes = {
* 200 = "Returned when successful",
* 400 = "Returned when the form has errors"
* }
* )
*
* #param ParamFetcher $paramFetcher Paramfetcher
*
* #CustomParam(name="username", value="foufou" ,nullable=false, strict=true, description="Username.")
* #CustomParam(name="email", value="foufou#gmail.com", nullable=false, strict=true, description="Email.")
* #CustomParam(name="password", value="foufou", nullable=false, strict=true, description="Password.")
* #CustomParam(name="plainPassword", value="foufou", nullable=false, strict=true, description="Plain Password.")
* #CustomParam(name="company_name", value="ffff", nullable=false, strict=true, description="Company.")
* #CustomParam(name="adress_zip", value="papappa", nullable=false, strict=true, description="Zip.")
* #CustomParam(name="adress_name", value="rue hhh",nullable=false, strict=true, description="Adress.")
* #CustomParam(name="adress_city", value="paris",nullable=false, strict=true, description="City.")
* #CustomParam(name="adress_country", value="France", nullable=false, strict=true, description="Country.")
*
* #return View
*/
public function postUserAction(ParamFetcher $paramFetcher)
{
$userManager = $this->container->get('fos_user.user_manager');
$user = $userManager->createUser();
$user->setUsername($paramFetcher->get('username'));
$user->setEmail($paramFetcher->get('email'));
$user->setPassword($paramFetcher->get('password'));
$user->setPlainPassword($paramFetcher->get('plainPassword'));
$user->setEnabled(true);
$user->addRole('ROLE_API');
$adress = new Adress();
$adress->setAdress($paramFetcher->get('adress_name'));
$adress->setCity($paramFetcher->get('adress_city'));
$adress->setZip($paramFetcher->get('adress_zip'));
$adress->setCountry($paramFetcher->get('adress_country'));
$company = new Company();
$company->setName($paramFetcher->get('company_name'));
$user->setAdress($adress);
$user->setCompany($company);
$view = View::create();
$errors = $this->get('validator')->validate($user, array('Registration'));
if (count($errors) == 0) {
$userManager->updateUser($user);
$view->setData($user)->setStatusCode(200);
return $view;
} else {
$view = $this->getErrorsView($errors);
return $view;
}
}
but i get this error, No #QueryParam/#RequestParam configuration for parameter 'username'

Related

Symfony/PhpUnit - How to test that an Exception is throws or not in a Service

I'm beginner with tests and I want to test my ValidatorService which throws an InvalidDataException when an entity data are not valid.
My ValidatorServiceTest function :
public function testValidatorForUser()
{
$validatorMock = $this->createMock(ValidatorInterface::class);
$contraintViolationMock = $this->createMock(ConstraintViolationListInterface::class);
$validatorMock->expects($this->once())
->method('validate')
->with()
->willReturn($contraintViolationMock);
$validatorService = new ValidatorService($validatorMock);
$user = new User();
$user->setEmail('test');
$validatorService->validate($user);
$this->expectException(InvalidDataException::class);
}
My ValidatorService :
class ValidatorService
{
/**
* #var ValidatorInterface
*/
private ValidatorInterface $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
/**
* #param $value
* #param null $constraints
* #param null $groups
* #throws InvalidDataException
*/
public function validate($value, $constraints = null, $groups = null)
{
$errors = $this->validator->validate($value, $constraints, $groups);
if (count($errors) > 0) {
throw new InvalidDataException($errors);
}
}
}
My User entity:
/**
* #ORM\Entity(repositoryClass=UserRepository::class)
* #ORM\Table(name="`user`")
* #UniqueEntity(fields="email", errorPath="email", message="user.email.unique")
* #UniqueEntity(fields="username", errorPath="username", message="user.username.unique")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private ?int $id;
/**
* #ORM\Column(type="string", length=180, unique=true)
* #JMS\Type("string")
* #JMS\Groups({"api"})
* #Assert\NotBlank(message="user.email.not_blank")
* #Assert\Email(message="user.email.email")
*/
private string $email;
/**
* #var string The hashed password
* #ORM\Column(type="string")
* #JMS\Type("string")
* #Assert\NotBlank(message="user.password.not_blank")
* #Assert\Length(min=8, minMessage="user.password.length.min")
*/
private string $password;
/**
* #JMS\Type("string")
* #Assert\NotBlank(message="user.confirm_password.not_blank")
* #Assert\EqualTo(propertyPath="password", message="user.confirm_password.equal_to")
*/
private string $confirmPassword;
...
...
I have this error :
1) App\Tests\Service\Validator\ValidatorServiceTest::testValidatorForUser
Failed asserting that exception of type "App\Exception\InvalidDataException" is thrown.
How can I test if an exception thows or not ?
SOLVED:
The problem was with my $contraintViolationMock which always returned empty data.
I have to retrieve violations before and test that it's match with the mock violations. I think, it's the more simple solution instead of creating manually a ConstraintViolationList.
If you have a better solution, i'll take it.
public function testValidatorForUser()
{
$user = new User();
$user->setEmail('test');
$validator = self::$container->get(ValidatorInterface::class);
$violations = $validator->validate($user);
$validatorMock = $this->createMock(ValidatorInterface::class);
$validatorMock->expects($this->once())
->method('validate')
->willReturn($violations);
$this->expectException(InvalidDataException::class);
$validatorService = new ValidatorService($validatorMock);
$validatorService->validate($user);
}

ManyToOne many Posts for one User -> creates new User by creating a Post

I am using Symfony and Doctrine.
I have two Entities, User and Pots.
Every logged User can create as many Post he want to.
Every Post is associated to one User.
Thats the Workflow: I log in with an User, this user create a Post. A New Post is saved in the Database with a foreigkey on the User wo create it.
Problem: when the User create the Post, the post ist create, but a new User is created too. The new Post is asssociate to the new Users and not to the logged User.
USER ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Post;
/**
* #ORM\Entity
* #ORM\Table(name= "User")
*/
class User
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 50)
*/
private $account;
/**
* #ORM\Column(type = "string", length = 22)
*/
private $password;
/**
* #ORM\Column(type = "string", length = 100)
*/
private $email;
/**
* #ORM\Column(type = "integer", length = 1)
*/
private $type;
/**
*
* #ORM\OneToMany(targetEntity="Post", mappedBy="user")
*/
private $posts;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set account
*
* #param string $account
*
* #return User
*/
public function setAccount($account)
{
$this->account = $account;
return $this;
}
/**
* Get account
*
* #return string
*/
public function getAccount()
{
return $this->account;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set mail
*
* #param string $mail
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get mail
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set type
*
* #param integer $type
*
* #return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
return $this;
}
/**
* Remove post
*
* #param \AppBundle\Entity\Post $post
*/
public function removePost(\AppBundle\Entity\Post $post)
{
$this->posts->removeElement($post);
}
/**
* Get posts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPosts()
{
return $this->posts;
}
}
POST ENTITY:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #ORM\Table(name = "Post")
* #Vich\Uploadable
*/
class Post
{
/**
* #ORM\Column(type = "integer")
* #ORM\Id
* #ORM\GeneratedValue("AUTO")
*/
private $id;
/**
* #ORM\Column(type = "string", length = 25)
*/
private $title;
/**
* #ORM\Column(type = "string", length = 255)
*/
private $text;
/**
* #ORM\Column(type= "string", length = 250)
*/
private $pic;
/**
* #Vich\UploadableField(mapping="post_file", fileNameProperty="pic")
*
*/
private $picFile;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="posts", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
public function getPicFile(){
return $this->picFile;
}
public function setPicFile(File $picFile = null){
$this->picFile = $picFile;
return $this;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
*
* #return Coach
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set title
*
* #param string $title
*
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set text
*
* #param string $text
*
* #return Post
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* #return string
*/
public function getText()
{
return $this->text;
}
/**
* Set pic
*
* #param string $pic
*
* #return Post
*/
public function setPic($pic)
{
$this->pic = $pic;
return $this;
}
/**
* Get pic
*
* #return string
*/
public function getPic()
{
return $this->pic;
}
/**
* Set id
*
* #param integer $id
*
* #return Post
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
CONTROLLER:
NOTE: Here is take the logged User from the SESSION. This works, i output the id from the User i use and it was the correct id.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$user = $session->get('user');
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post = $form->getData();
$post->setUser($user);
$doct = $this->getDoctrine()->getManager();
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
I left the Entity like you said, but i changed the Controller to. The Session User Object dind't work to associate it to the Post. So I just toke the ID from the Session and then search the user object again throw that id in the database and used this instade.
public function FrameCoachNewAction(Request $request)
{
$session = $request->getSession();
$session->start();
$users = $session->get('user');
$repo = $this->getDoctrine()->getRepository(User::class);
$user = $repo->find($users->getId());
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$doct = $this->getDoctrine()->getManager();
$post = $form->getData();
$post->setUser($user);
$doct->persist($post);
$doct->flush();
//return New Response($post->getUser()->getId());
return $this->RedirectToRoute('app_frame_coach');
}else{
return $this->render('/frame/frame_coach_new.html.twig', array('form' => $form->createView(), 'user' => $user));
}
}
The user is the strong side so you should move the cascade={"persist"} option to user, then the user can save the post not the other way. It seems the cascade={"persist"} option is rewriting the setUser method. When you use the cascade={"persist"} option that entity would create the targetEntity.
In addition to #Juan I. Morales Pestana
class User
{
// ...
/**
*
* #ORM\OneToMany(
* targetEntity="Post",
* mappedBy="user",
* cascade={"persist"}
* )
*/
private $posts;
// ...
/**
* Constructor
*/
public function __construct()
{
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add post
*
* #param \AppBundle\Entity\Post $post
*
* #return User
*/
public function addPost(\AppBundle\Entity\Post $post)
{
$this->posts[] = $post;
$post->setUser($this);
return $this;
}

You have requested a non-existent service \"user.handler\"

I have an error in my service restuser.handler, other services work, what's the problem please
services:
# rest_user.example:
# class: %rest_user.example.class%
# arguments: [#service_id, "plain_value", %parameter%]
restuser.form.register:
class: REST\UserBundle\Form\RegisterType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: rest_user_register}
restuser.form.profile:
class: REST\UserBundle\Form\ProfileType
arguments: [%fos_user.model.user.class%]
tags:
- { name: form.type, alias: rest_user_profile }
restuser.handler:
class: REST\UserBundle\Handler\UserHandler
arguments: [#doctrine.orm.entity_manager, #form.factory, #security.encoder_factory]
my controller is as follows:
class UserController extends FOSRestController{
/**
* #QueryParam(name="offset", requirements="\d+", nullable=true, description="Offset from which to start listing pages.")
* #QueryParam(name="limit", requirements="\d+", nullable=true, default="20", description="How many pages to return.")
*
* #View()
*
* #param Request $request the request object
* #param ParamFetcherInterface $paramFetcher param fetcher service
*
* #return array
*/
public function getUsersAction(Request $request, ParamFetcherInterface $paramFetcher)
{
$offset = $paramFetcher->get('offset');
$offset = null == $offset ? 0 : $offset;
$limit = $paramFetcher->get('limit');
return $this->container->get('user.handler')->all($limit, $offset);
}
/**
* #param User $user
*
* #View()
* #return array
*/
public function getUserAction($id)
{
$user=$this->getOr404($id);
return $user;
}
/**
*
* #View()
*
* #param Request $request
* #param int $id
*
* #return View
*
* #throws NotFoundHttpException when user not exist
*/
public function putUserAction(Request $request, $id)
{
try {
if (!($user = $this->container->get('user.handler')->get($id))) {
$statusCode = Codes::HTTP_CREATED;
$user = $this->container->get('user.handler')->post($request);
} else {
$statusCode = Codes::HTTP_NO_CONTENT;
$user = $this->container->get('user.handler')->put($user, $request);
}
$response = new Response('El usuario ha sido guardado con éxito', $statusCode);
return $response;
} catch (\Exception $exception) {
return $exception->getMessage();
}
}
/**
*
* #View()
*
* #param Request $request
* #param int $id
*
* #return FormTypeInterface|View
*
* #throws NotFoundHttpException when user not exist
*/
public function patchUserAction(Request $request, $id)
{
try {
if (($user = $this->getOr404($id))) {
$statusCode = Codes::HTTP_ACCEPTED;
$user = $this->container->get('user.handler')->patch($user, $request);
} else {
$statusCode = Codes::HTTP_NO_CONTENT;
}
$response = new Response('El usuario ha sido guardado con éxito', $statusCode);
return $response;
} catch (NotFoundHttpException $exception) {
return $exception->getMessage();
}
}
/**
*
* #View()
*
* #param Request $request
* #param int $id
*
* #return FormTypeInterface|View
*
* #throws NotFoundHttpException when user not exist
*/
public function deleteUserAction(Request $request, $id)
{
if (($user = $this->container->get('user.handler')->get($id))) {
$statusCode = Codes::HTTP_ACCEPTED;
$user = $this->container->get('user.handler')->delete($user);
} else {
$statusCode = Codes::HTTP_NO_CONTENT;
}
$response = new Response('El usuario se ha eliminado', $statusCode);
return $response;
}
/**
* Fetch the Page or throw a 404 exception.
*
* #param mixed $id
*
* #return PageInterface
*
* #throws NotFoundHttpException
*/
protected function getOr404($id)
{
if (!($page = $this->container->get('user.handler')->get($id))) {
throw new NotFoundHttpException(sprintf('The User \'%s\' was not found.',$id));
}
return $page;
}
}
my class user handler is a s follows:
public function __construct(EntityManager $em, FormFactoryInterface $formFactory, EncoderFactory $encoderFactory)
{
$this->em = $em;
$this->factory = $formFactory;
$this->encoderFactory = $encoderFactory;
}
public function get($id = null, $email = null)
{
if ($email) {
return $this->em->getRepository('UserBundle:User')->findOneBy(array('email' => $email));
}
return $this->em->getRepository('UserBundle:User')->find($id);
}
/**
* #param int $limit the limit of the result
* #param int $offset starting from the offset
*
* #return array
*/
public function all($limit = 20, $offset = 0, $orderby = null)
{
return $this->em->getRepository('UserBundle:User')->findBy(array(), $orderby, $limit, $offset);
}
/**
* Create a new User.
*
* #param $request
*
* #return User
*/
public function post(Request $request)
{
$user = new User();
return $this->processForm($user, $request, 'POST');
}
/**
* #param User $user
* #param $request
*
* #return User
*/
public function put(User $entity, $request)
{
return $this->processForm($entity, $request);
}
/**
* #param User $user
* #param $request
*
* #return User
*/
public function patch(User $entity, $request)
{
return $this->processForm($entity, $request, 'PATCH');
}
/**
* #param User $user
*
* #return User
*/
public function delete(User $entity)
{
$this->em->remove($entity);
$this->em->flush($entity);
}
/**
* Processes the form.
*
* #param User $user
* #param array $parameters
* #param String $method
*
* #return User
*
* #throws \Exception
*/
private function processForm(User $entity, Request $request, $method = "PUT")
{
$form = $this->factory->create(new AppUserType(), $entity, array('method' => $method));
$form->handleRequest($request);
if ($form->isValid()) {
$req = $request->request->get('user');
if (!$req) {
$req = $request->request->get('user');
}
if ($req['password']!= "") {
$entity->setPassword($req['password']);
}
$this->em->persist($entity);
$this->em->flush($entity);
return $entity;
}
return View::create($form, 400);
}
I tried to clear the cache and change name of service but still not work, please help me

How to refer to route name with FOSRestBundle

Candidate Controller
class DefaultController extends PreviewMeController
{
/**
* Complete registration process for candidate
*
* #ApiDoc(
* section="Candidate",
* tags={"common"},
* )
*
* #Rest\View()
* #Post("/ua/register/candidate/{token}")
*
* #param Request $request
* #return \FOS\RestBundle\View\View
*/
public function registerCandidateAction($token)
{
}
}
Candidate routing.yml
candidate_api_routes:
type: rest
prefix: /v1
resource: "CandidateBundle\Controller\DefaultController"
name_prefix: "api_1_c_"
AppBundle Controller
/**
* Register a new user on the website
*
* #ApiDoc(
* section="Common Functionalities",
* tags={"common"},
* requirements={
* {"name"="email", "dataType"="string", "description"="Email of user"},
* {"name"="username", "dataType"="string", "description"="Username. Keep this same as email address"},
* {"name"="first_name", "dataType"="string", "description"="First name of user"},
* {"name"="last_name", "dataType"="string", "description"="Last name of user"},
* {"name"="plainPassword", "dataType"="array", "requirement"="['first':'password','second':'password']", "description"="Plain password. Send as an array with 'first' and 'second' as array keys"},
* {"name"="user_type","dataType"="string","requirement"="employer|candidate","description"="Employer or candidate user type"}
* },
* statusCodes={
* 200 = "When user is successfully registered",
* 400="When there is a validation error in the registration process"
* }
* )
* #Post("/ua/register")
* #Rest\View()
*
* #param Request $request
* #return array|\FOS\RestBundle\View\View
*/
public function registerAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var UserManager $fos_userManager */
$fos_userManager = $this->get('fos_user.user_manager');
/** #var User $user */
$user = $fos_userManager->createUser();
$user->setEnabled(true);
$user->setUserType($request->request->get('user_type'));
//remove user_type from request so it's not forwarded to form
$request->request->remove('user_type');
$form = $formFactory->createForm();
$form->setData($user);
$form->submit($request->request->all());
if( $form->isValid() ){
$event = new UserEvent($user);
$dispatcher = $this->get('event_dispatcher');
$dispatcher->dispatch(PmEvents::REGISTRATION_SUCCESS, $event);
$fos_userManager->updateUser($user);
$wrapper = new PMResponseWrapper();
$wrapper->setData(array(
'ob_key' => $user->getObKey()
));
/** #var View $response */
$response = View::create($wrapper->getFormattedData());
$response->setLocation( $this->generateUrl('register_candidate') );
return $response;
}
return $this->view($form);
}
app/console debug:router dump
api_1_register POST ANY ANY /api/v1/ua/register
api_1_register_confirm_token POST ANY ANY /api/v1/ua/register/confirm_token/{token}
api_1_c_index GET ANY ANY /api/v1/index
api_1_c_register_candidate POST ANY ANY /api/v1/ua/register/candidate/{token}
Problem is even though registerCandidateAction shows up in debug:router, I am not able to call it with $this->generateUrl() in registerAction.
When I call this line $response->setNextUrl($this->generateUrl('register_candidate')); I get this error Unable to generate a URL for the named route \"register_candidate\" as such route does not exist.
Please help in finding what's wrong here.

Little innerJoin-Query

Old Query in symfony 1.4 and doctrine 1.2
$user = Doctrine_Query::create()
->from('User.u')
->innerJoin('u.State s')
->where('u.id = ?', $id)
->andWhere('u.state_id = ?', $state_id)
->fetchOne();
Now my Query in symfony2:
$repository = $this->getDoctrine()
->getRepository('FrontendAccountBundle:User');
$user = $repository->findBy(array(
'activationId' => $activation_id),
array('state' => 3));
My error is comming up:
Unrecognized field: state
What is the problem?
Edit: reformatted code
Update
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #var string
*
* #ORM\Column(name="activation_id", type="string", length=255, nullable=true)
*/
private $activationId;
/**
* #var \State
*
* #ORM\ManyToOne(targetEntity="State")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="state_id", referencedColumnName="id")
* })
*/
private $state;
/**
* Set activationId
*
* #param string $activationId
* #return User
*/
public function setActivationId($activationId)
{
$this->activationId = $activationId;
return $this;
}
/**
* Get activationId
*
* #return string
*/
public function getActivationId()
{
return $this->activationId;
}
/**
* Set state
*
* #param \Frontend\AccountBundle\Entity\State $state
* #return User
*/
public function setState(\Frontend\AccountBundle\Entity\State $state = null)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return \Frontend\AccountBundle\Entity\State
*/
public function getState()
{
return $this->state;
}
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* #inheritDoc
*/
public function getUsername()
{
return $this->email;
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
}
User-Entity:
namespace Frontend\AccountBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* State
*
* #ORM\Table(name="state")
* #ORM\Entity
*/
class State
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=255, nullable=false)
*/
private $state;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set state
*
* #param string $state
* #return State
*/
public function setState($state)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* #return string
*/
public function getState()
{
return $this->state;
}
/**
* Set description
*
* #param string $description
* #return State
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
The problem is that the variable in the User entity is "state" not "stateId". You must always use the names from the entity, not the database. The join from User to State also needs to be done since the stateId is in the State entity.
When joins are needed you are probably better off using queryBuilder or DQL.
Here's a post about joins in Doctrine 2 queryBuilder: doctrine 2 query builder and join tables
Here's the documentation from the Symfony Book for Doctrine: http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations
Here's an example from my project that is very similar to your problem:
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->select ('a.activityId, a.startTime, a.endTime, u.username')
->join('a.login','u')
->where('u.id = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
If I didn't need anything from the user table the query could be written as
$uid = 2;
$rep = $this->getDoctrine()->getRepository('DevondevTrackRTimeBundle:Activity');
$q = $rep->createQueryBuilder('a')
->where('a.login = :uid')
->setParameter('uid', $uid)
->getQuery();
$acts = $q->getResult();
This is your query reworked in the same way:
$rep = $this->getDoctrine()->getRepository('FrontendAccountBundle:User');
$q = $rep->createQueryBuilder('u')
->join('u.state','s')
->where ('u.id = :uid')
->andWhere ('s.stateId = :sid')
->setParameters(array('uid' => $id, 'sid' => $state_id))
->getQuery();
$user = $q->getSingleResult();
Thanks to Peter to light me up a little bit!!!
If you don't want again a the stupid solution from symfony2(-docs) and doctrine2, because you need much more code than in symfony1.4, like that way http://symfony.com/doc/current/book/doctrine.html#joining-to-related-records. Try my solution.
Here is the result.
$em = $this->getDoctrine()->getEntityManager();
$user = $em->createQuery('SELECT u FROM FrontendAccountBundle:User u
INNER JOIN FrontendAccountBundle:State s
WHERE
u.activation_id=:activation_id
and
u.state=:state_id
')
->setParameter('activation_id', $activation_id)
->setParameter('state_id', 3)
->getSingleResult();

Resources