2

I have a custom module that syncs LDAP-data to custom user fields (every 24 hours, depending on when the user logs in). Everything seems to be working, but I'm not an expert on PHP and Drupal hooks so I want to be sure I'm not doing anything silly.

My understanding is that when user account is saved in hook_user_login, hook_user_presave is run and the values are saved (values are located in the $edit variable). Am I saving the values correctly? Have I missed a critical check that could lead to errors?

Here's my code:

// runs everytime a user logs in, checks if ldap attributes need to be updated
function company_ldap_user_login(&$edit, $account) {

      // If the user is user 1 or guest, then do nothing
      if ($account->uid <= 1) {
        return;
      }

      // don't update data if it's less than 24 hours ago
      if (isset($account->data->ldap_sync) && $account->data->ldap_sync < time() - 3600 * 24) {
        return;
      } else {

        // load custom LDAP configuration
        require_once('custom_ldap.inc');

        $ldap = new ldap();

        // get LDAP data
        $data = $ldap->get_info();

        // do nothing, since user does not exist in LDAP
        if($data["count"] == 0)
        {                          
          return;
        }

        $data = $data[0];

        $first_name = trim($data["givenname"][0]);
        $last_name = trim($data["sn"][0]);
        $fullname = "$first_name $last_name";
        unset($data['mailaddresses']['count']);

        // load the user that has logged in
        $account = user_load($account->uid);

        // save LDAP data to an array
        $edits = array(
          'first_name' => $first_name,
          'last_name' => $last_name,
          'fullname' => $fullname,
          'emails' => $data['mailaddresses'],
          'ldap_sync' => time(),
        );

        // save the user with the data provided above
        user_save($account, $edits, 'company_ldap');

      }
}


// when user account is being saved or updated
function company_ldap_user_presave(&$edit, $account, $category) {

  // make sure to only update ldap-attributes when needed
  if ($category == 'company_ldap') {

    // if there is no data to save, don't save
    if (isset($edit['fullname'])) {

      // save ldap-data to custom user fields
      $edit['field_company_fullname'][LANGUAGE_NONE][0]['value'] = $edit['fullname'];
      $edit['field_company_first_name'][LANGUAGE_NONE][0]['value'] = $edit['first_name'];
      $edit['field_company_last_name'][LANGUAGE_NONE][0]['value'] = $edit['last_name'];

      // loop through all mail addresses and add them to the custom user field
      foreach ($edit['emails'] as $i => $email ) {
        $edit['field_company_emails'][LANGUAGE_NONE][$i]['value'] = $email;
      }

      // save serialized data of last ldap sync to users.data table
      $edit['data']['ldap_sync'] = $edit['ldap_sync'];
    }

  }

}
2

IMO you don't need the implementation of the hook_user_presave(), I see that in the implementation of hook_user_login() you have all the values that you need to create the user.

| improve this answer | |
  • I was thinking of that too, until I noticed I somehow couldn't save the ldap_sync data to the users.data table in the database (serialized) using user_save function. In hook_user_presave API it states that it is the preffered way to save serialized data: "This hook is primarily intended for modules that want to store properties in the serialized {users}.data column". Maybe the solution is to move the logic I have in hook_user_presave to hook_user_login instead? Saving the email variable is going to be trickier, I suppose. – Doombringah Jan 23 '16 at 22:36
  • @Doombringah If you want, you can check what's happens if you delete the hook_user_presave(), but I have a code similar to your code and it's works for me withour this hook. – Adrian Cid Almaguer Jan 23 '16 at 22:40
  • You are right, I won't need hook_user_presave(), I just have to modify how I save my variables in hook_user_login(). $edits['field_company_fullname'][LANGUAGE_NONE][0]['value'] = $fullname; will save to a custom user field, and $edits['data']['ldap_sync'] = time(); will save serialized data in users.data table. I have read conflicting reports on how I should save custom user data, some say using custom fields will cause heavier load on my site (every field creates two new tables in database), on the other hand you can't use serialized data in for example Views. What is your opinion? – Doombringah Jan 24 '16 at 12:08
  • @Doombringah This depend of your requirements, but 4 fields are not much. – Adrian Cid Almaguer Jan 25 '16 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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