0

I am trying to read a field collection and build an array in PHP.

The array I want to build goes like this:(it's in JS notation but you can easily imagine the equivalent in PHP)

highlights = [
{highlightTitle:A sample test title,
 highlightImage: a sample img url, 
 highlightBody: a sample text body},
{highlightTitle:A sample test title, 
 highlightImage: a sample img url,
 highlightBody: a sample text body}
]

As you can see it is just an array with objects inside, where each object represents a field collection entry. That field collection entry has 3 fields obviously, highlightTitle,highlightImage & highlightBody.

Now I want to read that field collection and build the array I described above.

The thing I care about is best practises. What is the best possible way to do this?

Currently I use the following code dumped in <?php ?> brackets on the top of my layout's tpl files: (I use Omega 4, and I have different layouts for different content types)

This is the code I use now:

  $highlightsArr; //this is the result array 
  $highlightsCounter = 0;
  $highlights = field_get_items('node', $node, 'field_highlights');


  foreach ($highlights as $item) {

    $fc = field_collection_field_get_entity($item);
    $highlightSnippet = $fc->field_highlight_snippet["und"][0]["value"];

    $arr = $fc->field_highlight_snippet["und"][$i]["value"];
    $innerArray = entity_load('field_collection_item', array($arr));

    $innerCounter = 0;
    foreach ($innerArray as $item) {

      $highlightsArr[$innerCounter]["sectionItemTitle"] = $item->field_highlights_title["und"][0]["value"];
      $highlightsArr[$innerCounter]["highlightsImage"] = file_create_url($item->field_highlights_image["und"][0]["uri"]);
      $highlightsArr[$innerCounter]["sectionItemPrice"] = $item->field_highlights_body["und"][0]["value"];

      $innerCounter++;
    }
  }

The issue with the above code:

The code above returns undefined variables/indexes on things that are obviously defined. When I first create a content type and want to view it's node, it returns errors. But as soon as I refresh the page the errors go away which seems rather strange to me.


In any case I would like to know best practises for doing this kind of stuff. Unfortunately I come from a strictly JS background (I'm a front-end dev), so Drupal and PHP is something new for me.

Many thanks in advance.

2 Answers 2

1

The code above returns undefined variables/indexes on things that are obviously defined.

As long as your PHP installation is not buggy, that's not possible. If the variable is defined, PHP won't tell you it isn't defined.

as soon as I refresh the page the errors go away which seems rather strange to me.

It's not strange - messages are held in the session so if you're doing something that invokes them in a template file (when the messages for the current page have already been prepared), you should expect to see this delayed reaction. Logic should never been in a template file, always a preprocess or process function.

Best practice is really a matter of opinion, but these are the two standard options for accessing fields on any entity type, Field Collection included.

Both alleviate the need to access the arrays directly, thereby decreasing the possibility of developer error.

2
  • Thanks, I think that's the type of answer I've been looking for. Keeping the logic in the template files seems, at least to me, much more intuitive for someone who opens up my code. Since every content-type has it's tpl file, I like the fact that I am containing everything in that file, apart from CSS. Is there any way to "clear" the session or emulate the preprocess behaviour within the template file itself? Dec 4, 2014 at 9:22
  • 1
    You asked for best practice - putting logic in a template file is (rightly) considered to be very bad practice. Up to you how you proceed :) You might want to read up on SoC if you're not familiar with it
    – Clive
    Dec 4, 2014 at 10:50
0

I think its because of $i. Try to change the code :

$i = 0; // define $i here before foreach
foreach ($highlights as $item) {
  // Your code
  $i++; // Increment $i at end of foreach
} 
2
  • thanks, is the road I am following the right one? Using for-each loops with $fc = field_collection_field_get_entity($item); ? Dec 4, 2014 at 9:12
  • You can use views if you are not doing anything rather than printing it otherwise foreach is good way. Dec 4, 2014 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.