7

How can I get a list of all the selected values ​​for a field?

For example I have a field called countries, and I want to get all countries selected for a certain node.

I need to have this list, because I want the region to be automatically selected in another field (regions), according to the chosen country.

Ex: I choose France in the countries, then automatically the European region is selected in regions

For now I can only copy the selected values ​​in the "countries" field, in the "regions" field, by doing this:

$node->field_regions = $node->field_countries;

Here is the result when I select France in the countries field :

Country: France

Regions: France

Edit: I tried with the function:field_get_items(), but all I get is an array:

$items = field_get_items('node', $node, 'field_countries', $node->language);

Something is wrong? I also tried with this but I get the same result...

$items = $node->field_countries[$node->language][0]

2 Answers 2

7

Because fields can have multiple values both of the methods you describe will return an array. Each of those array items will itself be an array, of all the possible columns for the field. In the case of text fields the only column you really need to worry about is the value column.

Assuming your particular field does not accept multiple values, or it does and you only want the first value, the following should work:

$items = field_get_items('node', $node, 'field_countries', $node->language);
$item = array_shift($items);
$value = $item['value'];

or

$value = $node->field_countries[$node->language][0]['value'];
3
  • Thank you this is exactly what I need. Just one more thing. My country field accepts multiple values. How do I get all values​​? I know I have to seriously study PHP
    – 118218
    Commented Apr 2, 2012 at 23:52
  • 1
    You would usually loop through them with a foreach, something like: foreach ($node->field_countries[$node->language] as $item) { $val = $item['value']; // Do something with $val }
    – Clive
    Commented Apr 2, 2012 at 23:55
  • It is important to always check if the array of items is empty, or if it is an array at all! I am going to write a new answer, because it is too much change for an edit.
    – donquixote
    Commented Feb 26, 2015 at 17:12
6

field_get_items() is the solution that is typically recommended. However, there are some caveats.

It is important to check if the field is empty. In this case field_get_items() returns false (which sucks).

$items = field_get_items('node', $node, 'field_countries', $node->language);
if (!empty($items)) {
  $item = reset($items);
  return $item['value'];
}
else {
  return NULL;
}

I think you can generally be sure that if an item exists, it will be in the zero [0] index. And isset() is a very robust thing. So the following works as well:

$items = field_get_items('node', $node, 'field_countries', $node->language);
return isset($items[0]['value']) ? $items[0]['value'] : NULL;

For some field types, the value is not in $item['value'] but in $item['tid'] or something else.
In the usual case (I can't think of an exception atm), the value will be the first thing in the $item array. So the following will also work, but this is more by coincidence than by design. So personally I would not count on it.
(If $items is a (non-empty) array, then we can safely (*) assume that every $item will be an array too, and not something else.)

$items = field_get_items('node', $node, 'field_countries', $node->language);
return isset($items[0]) ? reset($items[0]) : NULL;

The return value of field_get_items() is by-value, so it is generally ok to modify the $items array. This means you can use array_shift().

$items = field_get_items('node', $node, 'field_countries', $node->language);
return !empty($items) ? array_shift(array_shift($items)) : NULL;

(*) Most of the assumptions we make here are not based on language-level guarantees, but just on how Drupal generally works.

Btw the following trick can be helpful sometimes, but it is not a complete solution of the original question:

$items = field_get_items(..) ?: array();

This guarantees that $items is always an array. But for snippets above this does not really help us.

Your Answer

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

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