Error in php foreach iteration - php

I have this laravel collection called $articles_rows.
Collection {#320 ▼
#items: array:3 [▼
0 => array:6 [▼
"img_alt" => "<span>Original</span> gifts"
"class" => "personalised-gifts"
"elements" => array:2 [▼
0 => array:2 [▼
"id" => 2638
"type" => "ARTICLE"
]
1 => array:2 [▼
"id" => 2100
"type" => "ARTICLE"
]
]
]
1 => array:5 [▼
"img_alt" => "<span>Love</span> gifts"
"class" => "love-gifts"
"elements" => array:3 [▼
0 => array:2 [▼
"id" => 1072
"type" => "CATEGORY"
]
1 => array:2 [▼
"id" => 6186
"type" => "ARTICLE"
]
2 => array:2 [▼
"id" => 1028
"type" => "CATEGORY"
]
]
]
On the other hand, I have another collection called $cats_and_arts, this $cat_and_arts collection have extra information about the 'element' field in the $articles_rows collection.
This is my $cats_and_arts collection:
array:5 [▼
0 => {#313 ▼
+"type": "ARTICLE"
+"name": "Ceramic Mug"
+"resource_id": "2638"
+"seo": {#314 ▶}
}
1 => {#323 ▼
+"type": "CATEGORY"
+"name": "Personalised Blankets"
+"category": {#325 ▼
+"id": 1072
+"gallery_id": null
+"final": true
}
+"seo": {#326 ▶}
}
2 => {#327 ▼
+"type": "ARTICLE"
+"name": "Circle Cushion"
+"resource_id": "2100"
+"seo": {#328 ▶}
}
3 => {#329 ▼
+"type": "ARTICLE"
+"name": "Book"
+"resource_id": "6186"
+"seo": {#330 ▶}
}
4 => {#341 ▼
+"type": "CATEGORY"
+"name": "Gifts for men"
+"category": {#342 ▼
+"id": 1028
+"gallery_id": null
+"final": false
}
+"seo": {#343 ▶}
}
]
I want replace the $cats_and_arts CATEGORIES and ARTICLES by the $articles_rows elements field.
I want this final result:
Collection {#320 ▼
#items: array:3 [▼
0 => array:6 [▼
"img_alt" => "<span>Original</span> gifts"
"class" => "personalised-gifts"
"elements" => array:2 [▼
0 => {#313 ▼
+"type": "ARTICLE"
+"name": "Ceramic Mug"
+"resource_id": "2638"
+"seo": {#314 ▶}
}
2 => {#327 ▼
+"type": "ARTICLE"
+"name": "Circle Cushion"
+"resource_id": "2100"
+"seo": {#328 ▶}
}
]
]
1 => array:5 [▼
"img_alt" => "<span>Love</span> gifts"
"class" => "love-gifts"
"elements" => array:3 [▼
0 => {#323 ▼
+"type": "CATEGORY"
+"name": "Personalised Blankets"
+"category": {#325 ▼
+"id": 1072
+"gallery_id": null
+"final": true
}
+"seo": {#326 ▶}
}
1 => {#329 ▼
+"type": "ARTICLE"
+"name": "Book"
+"resource_id": "6186"
+"seo": {#330 ▶}
}
2 => {#341 ▼
+"type": "CATEGORY"
+"name": "Gifts for men"
+"category": {#342 ▼
+"id": 1028
+"gallery_id": null
+"final": false
}
+"seo": {#343 ▶}
}
]
]
And this is my code, but, return me an error
Undefined index:id in the line 'if($article_element['id'] ==
$extra_element->category->id)'
when the loop have more than one iteration:
foreach($articles_rows as &$article)
{
foreach($article['elements'] as &$article_element)
{
foreach($cats_and_arts as $extra_element)
{
if($extra_element->type == 'CATEGORY')
{
if($article_element['id'] == $extra_element->category->id)//Undefined index:id
{
$article_element = (array)$extra_element;
}
}
if($extra_element->type == 'ARTICLE')
{
if($article_element['id'] == $extra_element->article->id)
{
$article_element = (array)$extra_element;
}
}
}
}
}

When you reassign the value of $extra_element, you're "removing" the property id, which you are using in the if.
There are 2 solutions:
Keep the id in your object.
$article_element = array_merge((array)$extra_element, $article_element);
Modify your condition to make sure the property exists in your array.
if (array_key_exists('id', $article_element) && $article_element['id'] == $extra_element->category->id)

Your issue is coming from the use of an array reference iterator in:
foreach($article['elements'] as &$article_element) {...}
Because you later overwrite the entire array at $article_element, the foreach iteration cannot continue. This can probably be corrected by iterating with both a key and value and overwriting the array not by its iterator variable, but rather directly by its key in the parent array.
// Iterate the loop with a variable for the key
// instead of using a reference
foreach($article['elements'] as $key => $article_element)
{
foreach($cats_and_arts as $extra_element)
{
if($extra_element->type == 'CATEGORY')
{
if($article_element['id'] == $extra_element->category->id)//Undefined index:id
{
// Overwrite it by key in the parent array
$article['elements'][$key] = (array)$extra_element;
}
}
if($extra_element->type == 'ARTICLE')
{
if($article_element['id'] == $extra_element->article->id)
{
// And do the same here...
$article['elements'][$key] = (array)$extra_element;
}
}
}
}
Note: I didn't include the outermost loop here. It does not need modification as far as I can tell, although the array reference &$article is probably unnecessary. You may be able to use
foreach ($article_rows as $article) {...}
because I don't see anywhere that you modify that outer iterator.

Related

Laravel using unique for collections in relationships

getting data from database by this code:
$allTickets = Ticket::with(['user','replies','supporters'])->whereUserId(auth()->user()->id)->get();
return this result for me which that have 2 index in array and all of this items i have supporters relationship which both are same, now my question is how can i use unique in collections
Illuminate\Database\Eloquent\Collection {#1550 ▼
#items: array:2 [▼
0 => Modules\Ticket\Entities\Ticket {#1548 ▼
#guarded: array:1 [▶]
#connection: "mysql"
#table: "tickets"
...
#relations: array:3 [▼
"user" => App\User {#1575 ▶}
"replies" => Illuminate\Database\Eloquent\Collection {#1565 ▶}
"supporters" => Illuminate\Database\Eloquent\Collection {#1572 ▼
#items: array:1 [▼
0 => App\User {#1585 ▼
...
#attributes: array:19 [▼
"id" => 1
"user_id" => null
...
"api_token" => "a"
"remember_token" => null
"deleted_at" => null
"created_at" => "2020-06-14 13:56:45"
"updated_at" => "2020-06-14 13:56:45"
]
...
}
]
}
]
...
}
1 => Modules\Ticket\Entities\Ticket {#1567 ▼
#guarded: array:1 [▶]
#connection: "mysql"
#table: "tickets"
...
#relations: array:3 [▼
"user" => App\User {#1575 ▶}
"replies" => Illuminate\Database\Eloquent\Collection {#1551 ▶}
"supporters" => Illuminate\Database\Eloquent\Collection {#1559 ▼
#items: array:1 [▼
0 => App\User {#1585 ▼
...
#attributes: array:19 [▼
"id" => 1
"user_id" => null
...
"api_token" => "a"
"remember_token" => null
"deleted_at" => null
"created_at" => "2020-06-14 13:56:45"
"updated_at" => "2020-06-14 13:56:45"
]
...
}
]
}
]
...
}
]
}
my tested code:
#foreach($allTickets as $supporter)
#php
$unique = $supporter->supporters->unique();
#endphp
#foreach($unique->values()->all() as $user)
...
...
...
#endforeach
#endforeach
Do not try to do unique on the collection, try to get your data already filtered from your database. You could group by any of your relationships attributes, just pass in a closure to handle the query for the eager-loaded content, something like:
$allTickets = Ticket::with(['user','replies'])->with([
'supporters' => function($query) {
$query->groupBy('id');
}
])->whereUserId(auth()->user()->id)->get();
Or you can query like this:
$allTickets = collect(Ticket::with(['user','replies','supporters'])->whereUserId(auth()->user()->id)->get());
$allUniqueTickets = $allTickets->unique();
$tickets = $allUniqueTickets->values()->all();
That's how you can easily get all the unique values from your controller. I hope this answers your question.
For more information, you can check https://laravel.com/docs/7.x/collections#method-unique

Laravel view not having all properties passed in view

i am facing a issue in passing the values to laravel view
the object passed to view has values
Collection {#270 ▼
#items: array:2 [▼
0 => {#275 ▼
+"id": 3
+"category_id": 136
+"service_name": "ServiceName"
+"service_description": "fgdgfgfdg"
+"image": null
+"created_at": "2018-08-17 18:09:16"
+"updated_at": "2018-08-17 18:09:16"
+"something": Collection {#101 ▼
#items: array:2 [▼
0 => "ABC"
1 => "DEF"
]
}
}
]
}
and the object dd in the view is:-
Collection {#270 ▼
#items: array:2 [▼
0 => {#275 ▼
+"id": 3
+"category_id": 136
+"service_name": "ServiceName"
+"service_description": "fgdgfgfdg"
+"image": null
+"created_at": "2018-08-17 18:09:16"
+"updated_at": "2018-08-17 18:09:16"
}
]
}
how to get all the values (something property of the passed object).
I Solved this problem.
All you need to do is to check your view composer with the same

how can i print subscription from object

LengthAwarePaginator {#997 ▼
#total: 575
#lastPage: 58
#items: Collection {#1007 ▼
#items: array:10 [▼
0 => WorkableInterviews {#1008 ▶}
1 => WorkableInterviews {#1009 ▶}
2 => WorkableInterviews {#1010 ▶}
]
}
#perPage: 10
#currentPage: 1
#path: "https://localhost/employer/interviews/MQ=="
#query: array:1 [▼
"subscription" => array:1 [▼
0 => "prepaidxxxx"
]
]
#fragment: null
#pageName: "page"
}
my object is like this, I want to print this section query: array:1 subscription, How can do this

Filtering with Laravel

In my Laravel project I have the following problem. (I have reduced the output a little for easier readability)
I fetch all the posts from a table named Newsposts. I store this as a collection called $all_posts, which looks like this:
Collection {#216 ▼
#items: array:7 [▼
0 => NewsPost {#227 ▶}
1 => NewsPost {#228 ▶}
2 => NewsPost {#229 ▼
#attributes: array:6 [▼
"id" => 6
"title" => "Sample title"
"body" => "<p>Some html</p>"
"user_id" => 15
]
#original: array:6 [▶]
#casts: []
.
.
#guarded: array:1 [▶]
}
3 => NewsPost {#230 ▶}
4 => NewsPost {#231 ▶}
]
}
I then fetch all entries from another table called user_read witch contains all the posts the current user have read. This table contains a reference to the user with a 'user_id'-column, and a reference to the newsposts with a 'post_id'-column. I also store this in a collection, which looks like this:
Collection {#219 ▼
#items: array:2 [▼
0 => UserRead {#210 ▼
#attributes: array:4 [▼
"user_id" => 15
"post_id" => 6
]
#original: array:4 [▶]
#casts: []
.
.
#guarded: array:1 [▶]
}
1 => UserRead {#217 ▶}
]
}
So what I want to do now is take the $all_posts-collection and remove all the posts from $read_posts-collection, and store it in a new collection. Lets call it $unread_posts. How can i achieve this?
get all readed post id first, then use filter function to filter unread posts
$readedPosts = $user_read->pluck('post_id');
$unread_posts = $all_posts->filter(function($value) use ($readedPosts) {
return !in_array($value->id, $readedPosts);
})

Merge two Laravel collections elements and replace

I have this laravel collection called $box_items.
Collection {#320 ▼
#items: array:3 [▼
0 => array:6 [▼
"img_alt" => "<span>Original</span> gifts"
"class" => "personalised-gifts"
"elements" => array:2 [▼
0 => array:2 [▼
"id" => 2638
"type" => "ARTICLE"
]
1 => array:2 [▼
"id" => 2100
"type" => "ARTICLE"
]
]
]
1 => array:5 [▼
"img_alt" => "<span>Love</span> gifts"
"class" => "love-gifts"
"elements" => array:3 [▼
0 => array:2 [▼
"id" => 1072
"type" => "CATEGORY"
]
1 => array:2 [▼
"id" => 6186
"type" => "ARTICLE"
]
2 => array:2 [▼
"id" => 1028
"type" => "CATEGORY"
]
]
]
On the other hand, I have another collection called $elements, this $elements collection have extra information about the 'element' field in the $box_items collection.
This is my $elements collection:
array:5 [▼
0 => {#313 ▼
+"type": "ARTICLE"
+"name": "Ceramic Mug"
+"resource_id": "2638"
+"seo": {#314 ▶}
}
1 => {#323 ▼
+"type": "CATEGORY"
+"name": "Personalised Blankets"
+"category": {#325 ▼
+"id": 1072
+"gallery_id": null
+"final": true
}
+"seo": {#326 ▶}
}
2 => {#327 ▼
+"type": "ARTICLE"
+"name": "Circle Cushion"
+"resource_id": "2100"
+"seo": {#328 ▶}
}
3 => {#329 ▼
+"type": "ARTICLE"
+"name": "Book"
+"resource_id": "6186"
+"seo": {#330 ▶}
}
4 => {#341 ▼
+"type": "CATEGORY"
+"name": "Gifts for men"
+"category": {#342 ▼
+"id": 1028
+"gallery_id": null
+"final": false
}
+"seo": {#343 ▶}
}
]
I want replace the $elements CATEGORIES and ARTICLES by the $box_items elements field.
I want this final result:
Collection {#320 ▼
#items: array:3 [▼
0 => array:6 [▼
"img_alt" => "<span>Original</span> gifts"
"class" => "personalised-gifts"
"elements" => array:2 [▼
0 => {#313 ▼
+"type": "ARTICLE"
+"name": "Ceramic Mug"
+"resource_id": "2638"
+"seo": {#314 ▶}
}
2 => {#327 ▼
+"type": "ARTICLE"
+"name": "Circle Cushion"
+"resource_id": "2100"
+"seo": {#328 ▶}
}
]
]
1 => array:5 [▼
"img_alt" => "<span>Love</span> gifts"
"class" => "love-gifts"
"elements" => array:3 [▼
0 => {#323 ▼
+"type": "CATEGORY"
+"name": "Personalised Blankets"
+"category": {#325 ▼
+"id": 1072
+"gallery_id": null
+"final": true
}
+"seo": {#326 ▶}
}
1 => {#329 ▼
+"type": "ARTICLE"
+"name": "Book"
+"resource_id": "6186"
+"seo": {#330 ▶}
}
2 => {#341 ▼
+"type": "CATEGORY"
+"name": "Gifts for men"
+"category": {#342 ▼
+"id": 1028
+"gallery_id": null
+"final": false
}
+"seo": {#343 ▶}
}
]
]
EDIT: error in the line if($article_element['id'] == $extra_element->category->id);
foreach($articles_rows as &$article)
{
foreach($article['elements'] as &$article_element)
{
foreach($cats_and_arts as $extra_element)
{
if($extra_element->type == 'CATEGORY')
{
if($article_element['id'] == $extra_element->category->id)//Undefined index: id
{
$article_element = (array)$extra_element;
}
}
if($extra_element->type == 'ARTICLE')
{
if($article_element['id'] == $extra_element->article->id)
{
$article_element = (array)$extra_element;
}
}
}
}
}
dd($articles_rows);
Try this out. It should work for you.
foreach($box_items as &$box){
foreach($box["elements"] as &$box_element){
foreach($elements as $element){
if($box_element->id == $element->id){
$box_element = $element;
}
}
}
}

Categories