Laravel use toArray to add object to array and remove key [duplicate] - php

This question already has answers here:
How to remove index number from laravel eloquent unique
(2 answers)
Closed 3 years ago.
$message = Message::where('agent_id', $agent->id)->orderBy('id', 'DESC')->get();
I used unique() on collection and now I got this result:
{
"0": {
"id": 1,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "hello",
"status": 0
},
"3": {
"id": 4,
"post_id": 5,
"agent_id": 1,
"user_id": 2,
"message": "hi hello",
"status": 0
}
}
But I want to remove key index, I mean 0 and 3, desire output is:
[
{
"id": 1,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "hello",
"status": 0
},
{
"id": 4,
"post_id": 5,
"agent_id": 1,
"user_id": 2,
"message": "hi hello",
"status": 0
}
]
I tried:
$message->unique('user_id')->toArray();
But not working. any idea?
I using Laravel.

Use the values method of the Collection, similar to array_values:
$new = $message->values();
Assuming $message is the Collection holding the result of the unique call.
Laravel 6.x Docs - Collections - Available Methods - values

Try using group by groupBy('user_id')
$message = Message::where('agent_id', $agent->id)
->groupBy('user_id')
->orderBy('id', 'DESC')
->get();

Related

Remove elements from an eloquent query based on a condition between these elements

I have an eloquent request:
HealthItem::where('person_id', 1)
->orderBy('name', 'ASC')
->orderBy('date_in', 'DESC')
->get();
It returns a result like this :
[
{
"id": 26,
"name": "Test 1",
"date_in": "2020-06-24",
"date_end": "2020-09-24",
},
{
"id": 27,
"name": "Test 1",
"date_in": "2020-05-19",
"date_end": "2020-09-24",
},
{
"id": 28,
"name": "Test 2",
"date_in": "2020-09-19",
"date_end": "2020-09-24",
},
{
"id": 32,
"name": "Test 3",
"date_in": "2020-09-19",
"date_end": "2020-09-24",
}
]
I would like to keep only the different items with the most recent date date_in. For example, keep Test 1 with date_in = 2020-06-24 and remove from the results all old Test 1 (here, the one with the date_in = 2020-05-19)
Obviously, this is an example. There could be 5 or more Test 1 but I would always keep the one with the most recent date_in
Is it possible to do this?
You need to use distinct method.
HealthItem::where('person_id', 1)
->distinct('name')
->orderBy('name', 'ASC')
->orderBy('date_in', 'DESC')
->get();
Check Documentation

Laravel make data unique but remove first duplicate

I got data from db:
$message = Message::where('user_id', $user->id)->get();
Result:
[
{
"id": 1,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "hello",
"status": 0
},
{
"id": 2,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"sender_id": 1,
"message": "how are you?",
"status": 0
},
{
"id": 3,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "Ill call you",
"status": 0
},
{
"id": 4,
"post_id": 5,
"agent_id": 1,
"user_id": 2,
"message": "hi hello",
"status": 0
}
]
Well, I able to make it unique and remove duplicate by user_id with:
$message->unique('user_id')
It return right result, but what I want is, remove first item not last, current result:
{
"0": {
"id": 1,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "hello",
"status": 0
},
"3": {
"id": 4,
"post_id": 5,
"agent_id": 1,
"user_id": 2,
"message": "hi hello",
"status": 0
}
}
As you see, it keep first item and then removed next duplicate, in this case I want to keep id 3 and 4 also it made my object to array, I don't want this, how can I solve this?
But I want this result:
[
{
"id": 3,
"post_id": 3,
"agent_id": 1,
"user_id": 1,
"message": "Ill call you",
"status": 0
},
{
"id": 4,
"post_id": 5,
"agent_id": 1,
"user_id": 2,
"message": "hi hello",
"status": 0
}
]
To get the newest messages try sorting on id in a descending order
$messages = Message::where('user_id', $user->id)->orderBy('id', 'DESC')->get();
and you are receiving a Collection you call toArray on it to get back an array:
return $messages->unique('user_id')->toArray();
Use sorting before unique.
$message = Message::where('user_id', $user->id)->orderBy('id','desc')->get();
$message->unique('user_id');

LARAVEL : Add key and value in single array

I have a single array of data, I want to add a key and it's value in same array . Here in addedPost I want to add key favouritePost and it's value is $favouritePost after product key. How can i do this ?
Here is my query:
$addedPost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->whereId($postData['post_id'])
->first();
$favouritePost = PostFavourite::isAlreadyAdded($postData['post_id'], Auth::id());
return [
'status_code' => $status_code,
'message' => $message,
'PostDetails' => $addedPost
];
What I get in response :
{
"PostDetails": {
"id": 289,
"user_id": 12,
"product_id": 2,
"demand_or_supply": "Demand",
"description": "edited1",
"status": "Expired",
"created_at": "2018-06-22 07:35:27",
"updated_at": "2018-07-05 06:42:56",
"product": {
"id": 2,
"title": "Diamond",
"icon": null,
"status": "Active"
}
}
}
EXPECTED RESULT:
{
"PostDetails": {
"id": 289,
"user_id": 12,
"product_id": 2,
"demand_or_supply": "Demand",
"description": "edited1",
"status": "Expired",
"created_at": "2018-06-22 07:35:27",
"updated_at": "2018-07-05 06:42:56",
"product": {
"id": 2,
"title": "Diamond",
"icon": null,
"status": "Active"
},
"favouritepost": {
"id": 8,
"post_id": 289,
"user_id": 12
}
}
}
First: Your $addedPost is not an array but a Eloquent Collection. There are multiple possibilites to do this. The easiest one is to union an Array with the Collection.
$union = $addedPost->union($favouritePost->toArray());
For every other solution please take a look at the Laravel Documentation. It's pretty easy to understand.
https://laravel.com/docs/5.6/collections
Edit: Though I missed the ->first() inside the question just use the solution already mentioned. ->first() returns a StdClass Object, so you can handle it like it:
$addedPost->favouritepost = $favouritePost;
That property favouritePost is added to $addedPost object in that case. There's no need for any method call again.
first you store all the values which you are returning in one associative array then use array_push() to add new key/value in that array.After all you just return that array.
Assuming that $addedPost is a laravel collection you can simply do:
$addedPost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->whereId($postData['post_id'])
->first();
$favouritePost = PostFavourite::isAlreadyAdded($postData['post_id'], Auth::id());
$addedPost->put('favouritepost', $favouritePost);
return [
'status_code' => $status_code,
'message' => $message,
'PostDetails' => $addedPost
];
for adding key value in object
$object->new_key="value";

QueryBuilder limit is working for only first row in cakephp 3.2 [duplicate]

This question already has an answer here:
How to limit contained associations per record/group?
(1 answer)
Closed 6 years ago.
Hii i am new to cakephp 3.2 v.
Here i have used model association (hasMany).
Here in bind section (campaign_videos) ,i want to fetch only one record ,
so for this ,i have put below code to manage it.
my actual data in db.
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
{
"id": 3,
"campaign_id": 1,
}
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
{
"id": 2,
"campaign_id": 2,
}
]
},
$fetchCampaignFirst = $this->Campaigns->find()->contain(['CampaignVideos' => ['queryBuilder' => function ($q) {
return $q->limit(1);
}]]);
I am getting this limit working for first data only ,not for others (others even not showing the fetched data).
Below i have written the output
Here i want to get an output like
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
{
"id": 2,
"campaign_id": 2,
}
]
}]
Only want the first record of campaign_videos.
Here after using the queryBuilder query , i am getting out put like.
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
]
}]
I am not getting any data for second id ,while data is present for it.
Please suggest me.
Thank you in advance.
Maybe I'm wrong (so feel free to downvote my answer) but I think it's not feasible using a simple query
in fact cake, when loading associated data, does a single query on the associated table and after that matches the rows with the corresponding ones in the main table.
So you would need to do a mysql query that find the first record of every category. i.e. something like what is described in this article
I think that the only (or maybe the simpler) solution is to loop through your records:
$campaigns= $this->Campaigns->find();
foreach($campaigns as $campaign)
{
$campaign->campaign_videos = $this->Campaigns->CampaignVideos-find()
->where(['campaign_id' => $campaign->id]
->order(['id' => 'asc'])
->limit(1);
}

How to get only first row of association table in cakephp 3.2 [duplicate]

This question already has an answer here:
How to limit contained associations per record/group?
(1 answer)
Closed 6 years ago.
Hii i am new to cakephp 3.2 v.
Here i have used model association (hasMany).
Here in bind section (campaign_videos) ,i want to fetch only one record ,
so for this ,i have put below code to manage it.
my actual data in db.
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
{
"id": 3,
"campaign_id": 1,
}
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
{
"id": 2,
"campaign_id": 2,
}
]
},
$fetchCampaignFirst = $this->Campaigns->find()->contain(['CampaignVideos' => ['queryBuilder' => function ($q) {
return $q->limit(1);
}]]);
I am getting this limit working for first data only ,not for others (others even not showing the fetched data).
Below i have written the output
Here i want to get an output like
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
{
"id": 2,
"campaign_id": 2,
}
]
}]
Only want the first record of campaign_videos.
Here after using the queryBuilder query , i am getting out put like.
[
{
"id": 1,
"user_id": 95,
"campaign_videos": [
{
"id": 1,
"campaign_id": 1,
},
]
},
{
"id": 2,
"user_id": 95,
"campaign_videos": [
]
}]
I am not getting any data for second id ,while data is present for it.
Please suggest me.
Thank you in advance.
Maybe I'm wrong (so feel free to downvote my answer) but I think it's not feasible using a simple query
in fact cake, when loading associated data, does a single query on the associated table and after that matches the rows with the corresponding ones in the main table.
So you would need to do a mysql query that find the first record of every category. i.e. something like what is described in this article
I think that the only (or maybe the simpler) solution is to loop through your records:
$campaigns= $this->Campaigns->find();
foreach($campaigns as $campaign)
{
$campaign->campaign_videos = $this->Campaigns->CampaignVideos-find()
->where(['campaign_id' => $campaign->id]
->order(['id' => 'asc'])
->limit(1);
}

Categories