1

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;
                    }
                }
              }
           }
        }
Akshay
  • 700
  • 9
  • 23
RichardMiracles
  • 2,032
  • 12
  • 28
  • 46

2 Answers2

1

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:

  1. Keep the id in your object.

$article_element = array_merge((array)$extra_element, $article_element);

  1. 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)

Diogo Sgrillo
  • 2,601
  • 1
  • 18
  • 28
0

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.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390