Symfony3 doctrine orm find method - php

I am writing a Symfony3 appusing Doctrine ORM.
SO what i am trying to do is to find if a given email address exists in a table (every email is unique). so i have a user repository with some attributes I can easily persist data to the db but failing to retrive data.
/**
* #param $email
*/
public function findUserByEmail($email)
{
$user = $this->getDoctrine()
->getRepository('TestBundle:TestUser')
->find($email);
if (!$user) {
echo 'Error';die();
}
}
I know the var passed to the function contains a email string, but what i get in return is error and when i var_dump $user before the if statment i get null.
I followed the Symfony docs

Your User probably has a separate primary key field. the find() method on a repo only retrieves by primary key.
Repositories use __call to dynamically process findBy* and findOneBy* methods, so you could call it like this:
$repo = $this->getDoctrine()->getRepository('TestBundle:TestUser');
// magic find method
$user = $repo->findOneByEmail($email);
// explicit find method
$user = $repo->findOneBy(['email' => $email]);
// custom QueryBuilder
$user = $repo->createQueryBuilder('user')
->where('user.email = :email')
->setParameter('email', $email)
->getQuery()
->getSingleResult();
BTW: If you are validating this for a submitted form, there is a contraint that does this check for you: UniqueEntity

I think the problem is because you forgot to call getManager().
So the code would be:
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('TestBundle:TestUser')->findOneBy(['email' => $email]);
Hope it would help you!

Related

Obtaining a given item in a Doctrine ArrayCollection

Developing an API where at the start of every request, the provided API key is used to obtain the Account object which is associated with the request.
$account = $em->getRepository(Entity\Account\Account::class)
->findOneBy(['mainKey'=>$request->getHeaderLine('X-API-Key')]);
This Account entity contains a User's ArrayCollection where each of the User entities contains an username property which is unique for a given Account.
Given the username, how can I obtain the User entity? I can do something like the following, however, feel I should be doing differently.
$user = $em->getRepository(Entity\Account\User::class)
->findOneBy(['accountId'=>$account->getId(), 'username'=>'John.Doe']);
Thanks,
PS. I assume that findOneBy() is using a prepared statement behind the scenes and isn't subject to SQL injection, right?
PSS. I just assumed that an ArrayCollection holds a group of objects, but looking at some of the docs, am now not certain.
If Account is related to User (I suppose it is one-to-one), then Account should have $user property defined. And you can access it kinda:
$user = $account->getUser();
Where getUser is:
public function getUser()
{
return $this->user;
}
Both of these approaches seem to work:
$criteria = \Doctrine\Common\Collections\Criteria::create()
->where(\Doctrine\Common\Collections\Criteria::expr()->eq("username", $username));
$user = $users->matching($criteria)->current();
$expr = new \Doctrine\Common\Collections\Expr\Comparison('username', '=', $username);
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($expr);
$user = $users->matching($criteria)->current();

Eloquent query not finding user by email

I'm trying to find a user form a database with 'email' = $email and send them an email. When I try to echo the $user, I receive an error that it's not a string.
public function sendEmail($user)
{
Mail::to($user['email'])->Send(new VerifyEmail($user));
}
public function verifyEmail($email)
{
$user = User::where('email',$email);
$this->sendEmail($user ); //mail won't send
return view('auth.email.verifyemail')->with('email', $email);
}
Please help, thank you!
Your code has a few more issues than not being able to find the user, but let's address this first.
Explanation
Calling the where() method on the User::class is returning an instance of Illuminate\Database\Query\Builder and not the record that you are looking for.
To get a collection of records you can call fluently the get() method or in your case you can just get the first result by calling first().
More on the topic: Retrieving Single Models / Aggregates
Solution
$user = User::where('email', '=', $email)->first();
if(!$user) {
// handle the case if no user is found
}
echo $user->email // access the user's email address
Then you can call your sendmail method or whatever you need and pass the $user instance like this $this->sendmail($user)
$thisUser has only a query. You need to execute it to get the user. Try to get the first record:
$thisUser = User::where('email',$email)->first();

Symfony2 get new value after UPDATE query

in my Symfony2.8 app I got the following controller:
public function changetariffAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$user = $this->container->get('security.context')->getToken()->getUser();
$userid = $user->getId();
$tariff = $user->getTariff();//tariff1 here
$paymentForm = $this->createPaymentForm($user);
$paymentForm->handleRequest($request);
if($tariff != 'tariff2') {
$query = $em->createQuery('UPDATE My\UserBundle\Entity\User u SET u.tariff = :tariff2 WHERE u.id = :userid');
$query->setParameter('userid', $user->getId());
$query->setParameter('tariff2', 'tariff2');
$query = $query->getResult();//returns 1 here, tariff field in DB is set to tariff2 as expected
$query = $em->createQuery('SELECT u FROM My\UserBundle\Entity\User u WHERE u.id = :userid');//getting once again user entity but it did not change
$query->setParameter('userid', $user->getId());
$user = $query->getResult();
$tariff_upd = $user[0]->getTariff();//tariff1 here but I need tariff2!
//Also I tried to persist and flush user entity here but it did not work
return $this->render('MyBundle:Pages:tariffchangesuccess.html.twig', array(
'user' => $user,
'form' => $paymentForm->createView(),
'tariff' => $tariff_upd //still tariff1 but I need tariff2
));
}
return $this->render('MyBundle:Pages:tariffchangesuccess.html.twig', array(
'user' => $user,
'form' => $paymentForm->createView(),
'tariff' => $tariff
));
}
My Controller works ok and all the values are updated in my DB as expected but new values (tariff2) are not rendered in my twig template. New values are rendered only when I update the page in my browser (hit F5), but this is not an expected behavior. Any ideas how to fix that? Thank you.
Doctrine use something similar as cache and maybe your use of queries instead of natives methods short-circuit this system. Docrtine can handle your entities and know what to record and has been changed etc. But you have to use Doctrine functions or repositories for that, and not do it througt custom queries... The Doctrine way should be something like:
$em = $this->getDoctrine()->getManager();
$userid = $this->container->get('security.context')->getToken()->getUser()->getId()
// Get object user from DB values
$user = $em->getRepository('My\UserBundle:User')->findOneById($userid );
// Update tarif in the user object
$user->setTariff('tariff2');
// Let Doctrine write in the DB. The persist() may not be necesary as Doctrine already manage this object, but it's a good practise.
$em->persist($user);
$em-> flush();
// Doctrine should already have update the $user object, but if you really really want to be sure, you can reload it:
$user = $em->getRepository('My\UserBundle:User')->findOneById($userid );
You can use the refresh method of the EntityManager in order to:
Refreshes the persistent state of an entity from the database,
overriding any local changes that have not yet been persisted.
So add the refresh call, as example:
$query = $em->createQuery('SELECT u FROM My\UserBundle\Entity\User u WHERE u.id = :userid');//getting once again user entity but it did not change
$query->setParameter('userid', $user->getId());
$user = $query->getResult();
// Force refresh of the object:
$em->refresh($user);
$tariff_upd = $user[0]->getTariff();//tariff1 here but I need tariff2!
Hope this help

Doctrine findBy() calling method from entity

I need little help to call method from entity.
Here is the code I had try to execute.
$datat = $this->getDoctrine()
->getRepository('AppBundle:users')
->findBy(array('userId' => $userId));
after this, when I call
$data->getUser();
I get message about exeption "Error: Call to a member function getUser() on a non-object"
When I dump $data I got data from table or if I execute
->find() with ID value.
findBy returns generally an ArrayCollection.
You should use findOneBy instead in order to target only one entity...
So :
$datat = $this->getDoctrine()
->getRepository('AppBundle:users')
->findOneBy(array('userId' => $userId));
Your method getUser() doesn't exist in users entity.
Just iterate over your $datat and called method from user object like that
foreach ($users as $user) {
// $user is an instance of users
echo $user->getName(); //if this method exist in your entity model
}

Delete records in Doctrine

I'm trying to delete a record in Doctrine, but I don't know why it's not deleting.
Here is my Code:
function del_user($id)
{
$single_user = $entityManager->find('Users', $id);
$entityManager->remove($single_user);
$entityManager->flush();
}
Plus: How can I echo query to see what going on here?
This is an old question and doesn't seem to have an answer yet. For reference I am leaving that here for more reference. Also you can check the doctrine documentation
To delete a record, you need to ( assuming you are in your controller ):
// get EntityManager
$em = $this->getDoctrine()->getManager();
// Get a reference to the entity ( will not generate a query )
$user = $em->getReference('ProjectBundle:User', $id);
// OR you can get the entity itself ( will generate a query )
// $user = $em->getRepository('ProjectBundle:User')->find($id);
// Remove it and flush
$em->remove($user);
$em->flush();
Using the first method of getting a reference is usually better if you just want to delete the entity without checking first whether it exists or not, because it will not query the DB and will only create a proxy object that you can use to delete your entity.
If you want to make sure that this ID corresponds to a valid entity first, then the second method is better because it will query the DB for your entity before trying to delete it.
For my understanding if you need to delete a record in doctrine that have a doctrine relationship eg. OneToMany, ManyToMany and association cannot be easy deleted until you set the field that reference to another relation equal to null.
......
you can use this for non relation doctrine
$entityManager=$this->getDoctrine()->getManager();
$single_user=$this->getDoctrine()->getRepository(User::class)->findOneBy(['id'=>$id]);
$entityManager->remove($single_user);
$entityManager->flush();
but for relation doctrine set the field that reference to another relation to null
$entityManager=$this->getDoctrine()->getManager();
$single_user=$this->getDoctrine()->getRepository(User::class)->findOneBy(['id'=>$id]);
{# assume you have field that reference #}
$single_user->setFieldData(null);
$entityManager->remove($single_user);
$entityManager->flush();
do you check your entity as the good comment annotation ?
cascade={"persist", "remove"}, orphanRemoval=true
In a Silex route I do like this, in case it helps someone:
$app->get('/db/order/delete', function (Request $request) use ($app) {
...
$id = $request->query->get('id');
$em = $app['orm.em']; //or wherever your EntityManager is
$order = $em->find("\App\Entity\Orders",$id); //your Entity
if($order){
try{
$em->remove($order);
$em->flush();
}
catch( Exception $e )
{
return new Response( $e->getMessage(), 500 );
}
return new Response( "Success deleting order " . $order->getId(), 200 );
}else{
return new Response("Order Not Found", 500);
}
}
You first need repository.
$entityManager->getRepository('Users')->find($id);
instead of
$single_user = $entityManager->find('Users', $id);
'Users' String is the name of the Users repository in doctrine ( depends if you are using Symfony , Zend . . etc ).
First, You may need to check if 'Users' is your fully qualified class name. If not check, and update it to your class name with the namespace info.
Make sure the object returned by find() is not null or not false and is an instance of your entity class before calling EM's remove().
Regarding your other question, instead of making doctrine return SQL's I just use my database (MySQL) to log all queries (since its just development environment).
try a var_dump() of your $single_user. If it is "null", it doens't exist ?
Also check if "Users" is a valid Entity name (no namespace?), and does the $id reference the PK of the user?
If you want to see the queries that are executed check your mysql/sql/... log or look into Doctrine\DBAL\Logging\EchoSQLLogger

Categories