Doctrine Query Builder Result: not looping correctly - php

I'm not sure if it's that I'm not doing correctly but this is giving me an error:
I have 2 Entities: Task and TaskUser. They are connected by a onetoMany.
What I want to do is this:
foreach($tasks as $task){
echo $task->getTitle;
echo $task->getTaskUser()->getFirstName();
}
This is my query in the Task Repository:
public function findTasksByUsers($user = false)
{
if($user){
$qb = $this->_em->createQueryBuilder();
$qb
->select('t', 'tu')
->from('\Entities\Task', 't')
->leftJoin('\Entities\TaskUser', 'tu', \Doctrine\ORM\Query\Expr\Join::WITH, 't.id = tu.task')
->where('tu = :user')
->setParameter('user', $user)
->orderBy('t.createDate', 'DESC');
return $qb->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_OBJECT);
}
}
When I do this loop:
$tasks = $this->em->getRepository('\Entities\Task')->findTasksByUsers($user);
foreach($tasks as $task){
echo $task->getTitle();
}
I get the the title of the first task, and then an error like this:
Title of first task
Fatal error: Call to undefined method Entities\TaskUser::getTitle() in D:\sites\db\application\controllers\TasksController.php on line 35
Any idea why this is happening? Thanks!

$qb->select('t', 'tu')
the issue is here as you're selecting both entities.
If you want only Task entity modify your DQL as follows
$qb->select('t')
However, to me, you could only procede that way (in your controller; if you aren't into controller, use DI to access entity manager)
//retrieve all TaskUser object
$em = $this->getDoctrine()->getManager();
$tu_repo = $em->getRepository('YourBundleName:TaskUser');
$tu_array_collection = $tu_repo->findBy(array('user'=>$user));
foreach ($tu_array_collection as $tu) {
$first_name = $tu->getFirstName();
foreach ($tu->getTasks() as $task) {
echo $first_name;
echo $task->getTitle();
}
}
of course you may need to adapt your code with right findBy array, and with correct methods from TaskUser entity

Related

Laravel/LaraCSV Managing Complex Relationships

I'm running into some issues with my Collection/Model relationships with regards to LaraCSV. Here is its documentation: https://github.com/usmanhalalit/laracsv#full-documentation. I have 3 models that interact right now: Doctor, Patient, Script
Doctor belongsToMany Patient
Patient belongsToMany Doctor
Patient hasMany Script
Script belongsTo Patient
I also created a relationship link inside of my Doctor model that can be used to tie Doctor to Script, but does not appear to work in this instance:
public function scripts() {
$this->load(['patients.scripts' => function($query) use (&$relation) {
$relation = $query;
}]);
return $relation;
}
What I am attempting to do is allow admin staff and our users to download CSV files that contain all of their scripts. While this works fine for admin staff as I can reference the models directly, I am not able to make it work for users because they are tied to the doctors, and I cannot seem to tie this into scripts as normal. Here is a perfectly working version for admin staff:
$doctors = Doctor::orderBy('last_name', 'asc')->get();
$patients = Patient::orderBy('last_name', 'asc')->get();
$scripts = Script::orderBy('prescribe_date', 'desc')->get();
$csvExporter->beforeEach(function ($script) use ($doctors, $patients) {
$patient = $patients->where('id', $script->patient_id)->first();
$doctor = $patient->doctors->first();
$script->patient = $patient->full_name;
$script->doctor = $doctor->full_name;
});
Here is how the user-specific version appears:
$doctors = User::
find(Auth::user()->id)
->doctors()
->orderBy('last_name', 'asc')
->get();
$patients = Patient::orderBy('last_name', 'asc')->get();
$scripts = $doctors->scripts()->get();
Trying to chain in my Doctor model scripts() function results in an error: Method Illuminate\Database\Eloquent\Collection::scripts does not exist.
$doctors = User::
find(Auth::user()->id)
->doctors()
->orderBy('last_name', 'asc')
->get();
$patients = array();
$scripts = array();
foreach ($doctors as $doctor_fe) {
foreach ($doctor_fe->patients as $patient_fe) {
$patients[] = $patient_fe;
foreach ($patient_fe->scripts as $script_fe) {
$scripts[] = $script_fe;
}
}
}
I also tried to pull the information using arrays, but unfortunately, it must be a Collection passed in via this error: Argument 1 passed to Laracsv\Export::addCsvRows() must be an instance of Illuminate\Database\Eloquent\Collection, array given
I settled by placing all of the patients belonging to the user's doctors through a foreach loop, then using another one to grab the patient's id. I then took the patient's id array and used the whereIn function to compare the Script's patient_id field to get the correct strips.
$doctors = User::
find(Auth::user()->id)
->doctors()
->orderBy('last_name', 'asc')
->get();
$patients_array = array();
foreach ($doctors as $doctor_fe) {
$patients_fe = $doctor_fe->patients;
foreach ($patients_fe as $patient_fe) {
$patients_array[] = $patient_fe->id;
}
}
$patients = Patient::orderBy('last_name', 'asc')->get();
$scripts = Script::whereIn('patient_id', $patients_array)->get();
$csvExporter->beforeEach(function ($script) use ($doctors, $patients) {
$patient = $patients->where('id', $script->patient_id)->first();
$patient_initials = substr($patient->first_name, 0, 1) . substr($patient->last_name, 0, 1);
$doctor = $patient->doctors->first();
$script->patient = $patient_initials;
$script->doctor = $doctor->full_name;
});
If I interpret you question correctly, you want to get all scripts of all patients of a doctor. Laravel provides the hasManyThrough() Method for this:
class Doctor extends Model
{
/**
* Get all of the scripts for the patient.
*/
public function scripts()
{
return $this->hasManyThrough(App\Script::class, App\Patient::class);
}
}
The first param is the model you want to get (the scripts); the 2nd param is the intermediate model (the patient).
To use it:
$doctor = Doctor::first();
$scripts = $doctor->scripts;

Retrieving data from database and passing it as instance of entity

I'm trying to pass id from query from one database table to another table to which is related.
But, since they are related I have to pass it as instance of the entity(class) to which is related.
This is error I got:
Argument 1 passed to App\Entity\KeywordRating::setKeywordId() must be an instance of App\Entity\Keywords, integer given, called in C:\xampp\htdocs\ratingAPI\src\Service\KeywordRatingService.php on line 26
This is my code:
public function insertRating($params, ObjectManager $manager, KeywordsRepository $keyRep, ProvidersRepository $provRep)
{
$keywordId = $keyRep->checkKeyword(strtolower($params['keyword']))->getId();
$providerId = $provRep->checkProvider($params['provider'])->getId();
$rating = new KeywordRating();
$rating->setKeywordId(<Keywords instance> $keywordId);
$rating->setProviderId(<Providers instance> $providerId);
if($params['attr'] === 'rocks')
{
$rating->setRocksRating($params['rating']);
$rating->setSucksRating(0);
} else
{
$rating->setRocksRating(0);
$rating->setSucksRating($params['rating']);
}
$rating->setRocksVotes(10);
$rating->setSucksVotes(8);
$rating->setSumVotes(18);
$rating->setScore(2.50);
$manager->persist($rating);
$manager->flush();
}
This is sql query:
public function checkKeyword($keyword)
{
return $this->createQueryBuilder('k')
->where('k.keyword_name = :val')
->setParameter('val', $keyword)
->getQuery()
->getOneOrNullResult();
}
checkProvider() is the same, only different parameters.
How do I do that?
Assuming you have a namespace called Entities where you have all your entities classes, you can try something like this:
$entityManager = $this->getDoctrine()->getManager();
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select('keyword')
->from('App\Entity\Keywords', 'keyword')
->where($queryBuilder->expr()->eq('keyword.keyword_name', $queryBuilder->expr()->literal($keyword)));
$result = $queryBuilder->getQuery()-> getOneOrNullResult();
return $result;

BadMethodCallException in Macroable.php line 81:Method update does not exist

I an developing a page to create, update, delete and view an event in which there is error while updating the event. There is a event table and a event_collection table. In that event_collection table there is event_id which is id of an event and a collection_id which is from other table collection.
When i create an event, all the data gets stored in event table except the collection one. in the collection table data gets stored in one by one manner like if I check 2 items in collection, it will generate 2 ids with same event_id and 2 collection_ids.
There is problem in update, when i try to update the code, it gives me error as
BadMethodCallException in Macroable.php line 81:
Method update does not exist.
Update method is:
public function update(EventRequest $request, $id)
{
$event = Event::findOrFail($id);
$input = $request->all();
$input['days_of_week'] = serialize(Input::get('days_of_week'));
$query = $event->update($input);
$checkbox_selection = Input::get('agree');
$choosen_checkbox = $id;
$collection_event = EventCollection::where('event_id',$choosen_checkbox)->get();
// return $collection_event;
if (!is_null($checkbox_selection)) {
foreach ($checkbox_selection as $collection) {
// $collection_id = $id;
foreach($collection_event as $k){
// return $k;
if($k->event_id == $choosen_checkbox){
$data = $request->all();
$data['event_id']= $choosen_checkbox;
$data['collection_id'] = $collection;
$collection_event->update($data);
}
}
}
}
My store method is:
public function store(Request $request)
{
$checkbox = Input::get('days_of_week');
$checkbox_selection = Input::get('agree');
// return $checkbox_collection;
$input = $request->all();
$input['days_of_week'] = serialize($checkbox);
$query = Event::create($input);
$event_id = $query->id;
$pro_id = $query->provider_org_id;
/*For the checkbox selection, if they are multiple store each separately*/
if (!is_null($checkbox_selection)) {
foreach ($checkbox_selection as $collection) {
$collection_id = $query->id;
if($collection_id){
$data = $request->all();
$data['event_id']= $collection_id;
$data['collection_id'] = $collection;
$create_collection = EventCollection::create($data);
}
}
}
return view('event.pic_upload',compact('event_id','pro_id'));
}
Store method works properly! Can someone please tell any solution? I am badly stucked in this.
I do not think the 'update' method works on collections.
This line will return a collection
$collection_event = EventCollection::where('event_id',$choosen_checkbox)->get();
You do not want a collection, rather a query. As given in the docs:
`App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);`
Try removing the '->get()' from the statement.

Laravel Eloquent Save Item

When I try to save an item in Laravel it says the following.
Call to undefined method Illuminate\Database\Query\Builder::save()
I have followed the documentation, and i can delete items fine just not update. Is there anything wrong with my code?
public function publishedMain($id, $state){
$userId = Auth::user()->id;
$userAdmin = Auth::user()->admin;
if($userAdmin == "0"){
$clients = Clients::whereRaw('id = ? and parent = ?', array($id, $state));
$clients->active = $state;
$clients->save();
die('not admin');
}else{
$clients = Clients::whereRaw('id = ?', array($id));
$clients->active = $state;
$clients->save();
die('admin');
}
}
Many Thanks
Brent
You call the save() method on the query builder, not on your model.
You're missing the ->first() piece:
$clients = Clients::whereRaw('id = ? and parent = ?', array($id, $state))->first();
Of course, this will get the first client, so naming the variable $clients makes not much sense.
You shall also check if your $clients variable is not null, in which case it didn't find anything.
(btw, your model should be called Client, not Clients)

Query builder Call to a member function createQueryBuilder() on a non-object

I'm trying to use Query Builder in Symfony2.3 and I keep getting the error:
FatalErrorException: Error: Call to a member function createQueryBuilder()
on a non-object in...line 45
which is the second part of my query,
$query = $tokenobject->createQueryBuilder('t')
->select('t.token','t.user', 't.expirationdate')
->where('t.user = :username','t.token = :token')
->setParameter('username', $Username)
->setParameter('token', $Token)
->orderBy('t.expirationdate', 'ASC')
->setMaxResults(1);
The entire code if it helps:
$confirmationrepository = $this->getDoctrine()
->getRepository('TravelTravelBundle:Confirmation')
->findByuser($Username);
$query = $confirmationrepository ->createQueryBuilder('t')
->select('t.token','t.user', 't.expirationdate')
->where('t.user = :username','t.token = :token')
->setParameter('username', $Username)
->setParameter('token', $Token)
->orderBy('t.expirationdate', 'ASC')
->setMaxResults(1);
$token = $query->getResult();
I know for a fact $confirmationrepository is finding table column'user' properly and that $Username and $Token (being routed into controller) are set and routing properly.
Is there something wrong with my syntax, or is there some other explanation for what is happening?
$confirmationrepository = $this->getDoctrine()
->getRepository('TravelTravelBundle:Confirmation')
->findByuser($Username);
should be
$confirmationrepository = $this->getDoctrine()
->getRepository('TravelTravelBundle:Confirmation');
->findByuser($Username); fetches an array of entries. So $confirmationrepository is an array, and not the repository class you expected. Just omit the findByuser line.

Categories