In various locations, the array returned by field_get_items() is accessed directly by $item['value'], which is not always correct. The countries module, for example, keeps its value in $item['iso2']. field_view_value() should be used to get the value, instead.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

blc’s picture

Using field_view_value() did not work so well, and it's probably best not to try to use a renderable array anyway.

One thought is to include it in the attribute map. Something like 'drupal' => '#field_country[iso2]'. I'm not sure how the "iso2" value would be discoverable by end users, though.

q0rban’s picture

I don't think we want field_view_value() here. There is the case where you want the raw value stored in the column, not the display value. The real problem is that the column names don't match, as described in #1995602: Allow mapping of fields with columns other than value.

blc’s picture

Title: Use field_view_value() instead of accessing the item array directly » Account for fields with column names other than 'value'
q0rban’s picture

One possibility is to have the field mapping array optionally contain the column names in them.

For instance:


$variables['simple_ldap_user_attribute_map'] = array (
  array (
    'drupal' => '#field_firstname[value]',
    'ldap' => 'givenName',
  ),
  array (
    'drupal' => '#field_lastname[value]',
    'ldap' => 'sn',
  ),
  array (
    'drupal' => '#field_country[iso2]',
    'ldap' => 'country',
  ),
);

[value] would be implied, so this would also work:


$variables['simple_ldap_user_attribute_map'] = array (
  array (
    'drupal' => '#field_firstname',
    'ldap' => 'givenName',
  ),
  array (
    'drupal' => '#field_lastname',
    'ldap' => 'sn',
  ),
  array (
    'drupal' => '#field_country[iso2]',
    'ldap' => 'country',
  ),
);

blc’s picture

I was hoping to avoid explicitly specifying the field column in the config, since that is a little difficult to find. But, after digging into field API more, I think this might be the only reasonable option.

q0rban’s picture

Status: Active » Needs review
FileSize
18.47 KB

Ok, here is a patch that moves the mapping into it's own class.

@blc, a few things to note:

  • I changed that one place where it was only saving values from LDAP if they were different than what was on the user object, as I was thinking that created a hole for other modules to insert values into the edit array for those attributes. So, with this patch, it will always write what is in LDAP to what is in Drupal, no matter if the data already matches on the user. I think this is safer. Let me know what you think.
  • This still needs to have the simpletests run against it. I'm sure something will pop up from that, so let me know what needs to be fixed when you run those.
q0rban’s picture

Also, I would carefully review this patch, as it looked like a few other commits went in while I was working on this, so I want to make sure I didn't break anything you did before.

q0rban’s picture

FileSize
29.69 KB

Whoops, I forgot to git add the SimpleLdapUserMap class. Also, I've added some documentation and strictly declared some arguments since I last tested this, so I may have broken something in that process. Let me know if so, and I will re-roll.

blc’s picture

Status: Needs review » Fixed

Committed, thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.