gallery_user.inc 23.1 KB
Newer Older
1 2 3
<?php
// $Id$

4 5
require_once(drupal_get_path('module', 'gallery') .'/gallery_groups.inc');

6 7
/**
 * gallery.module : gallery_user.inc
8
 * User Functions (insert, update, delete, view, details, ...)
9
 */
10
 
11 12 13 14 15
define('GALLERY_MAP_UNKNOWN',                             0);
define('GALLERY_MAP_USER_EXISTS',                         1);
define('GALLERY_MAP_USER_EXISTS_BUT_NEEDS_MAPPING',       2);
define('GALLERY_MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED',   3);
define('GALLERY_MAP_USER_DOES_NOT_EXIST',                 4);
16

17 18 19 20 21 22 23 24 25 26
define('GALLERY_USERINFO_NOERROR',                        1);
define('GALLERY_USERINFO_ERROR',                          2);
define('GALLERY_USERINFO_ERROR_MISSING',                  3);
define('GALLERY_USERINFO_ERROR_USERNAME',                 4);
define('GALLERY_USERINFO_ERROR_FULLNAME',                 5);
define('GALLERY_USERINFO_ERROR_FULLNAME_MISSING',         6);
define('GALLERY_USERINFO_ERROR_EMAIL',                    7);
define('GALLERY_USERINFO_ERROR_PASSWORD',                 8);
define('GALLERY_USERINFO_ERROR_HASHMETHOD',               9);
define('GALLERY_USERINFO_ERROR_GROUPS',                  10);
27

28 29
define('GALLERY_IMPORT_CONFLICT_DUPLICATE',               1);
define('GALLERY_IMPORT_CONFLICT_INVALID',                 2);
30 31
 
/**
32 33
 * Function gallery_user_insert().
 * (insert new user)
34
 */
35 36 37
function gallery_user_insert(&$edit, $user) {
    $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
    $user->status = isset($edit['status']) ? $edit['status'] : TRUE;
38
    
39
    gallery_user_modify($user, 'create');
40 41 42
}

/**
43 44
 * Function gallery_user_update().
 * (update a user with new information)
45
 */
46
function gallery_user_update(&$edit, $user) {
47
  $user->language = isset($edit['language']) ? $edit['language'] : gallery_get_language('', $user);
48 49 50 51
  $user->pass = !empty($edit['pass']) ? md5($edit['pass']) : $user->pass;
  $user->status = isset($edit['status']) ? $edit['status'] : $user->status;
  $user->mail = !empty($edit['mail']) ? $edit['mail'] : $user->mail;
  $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  // Fullname support
  if (module_exists('profile') && variable_get('gallery_use_fullname', 0)) {
    $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
    $user->$fullname_field = isset($edit[$fullname_field]) ? $edit[$fullname_field] : $user->$fullname_field;
  }
  
  // Username is about to change
  if ($namechange = (isset($edit['name']) && ($edit['name'] != $user->name))) {
    // Make sure the original user is up to date
    gallery_user_modify($user, 'update', TRUE);
  }
  
  $user->name = isset($edit['name']) ? $edit['name'] : $user->name;
  
  if ($namechange) {
    // Change username
    gallery_user_modify($user, 'username');
  }
  else {
    // Update user
    gallery_user_modify($user, 'update', TRUE);
  }
75 76 77
}

/**
78 79
 * Function gallery_user_delete().
 * (delete the user from the Gallery)
80
 */ 
81 82
function gallery_user_delete($user) {
  gallery_user_modify($user, 'delete');
83 84 85
}

/**
86 87
 * Function gallery_user_modify().
 * (modify (create/update/delete) a user)
88
 */
89 90 91 92
function gallery_user_modify($user, $action = 'create', $groups = FALSE, $vars = NULL) {
  if (!_gallery_init(TRUE, $vars)) {
    return FALSE;
  }
93

94 95 96 97 98 99 100 101
  // Check for fullname support
  $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
  $usefullname = module_exists('profile') && variable_get('gallery_use_fullname', 0);
  $fullname = $usefullname ? (isset($user->$fullname_field) ? $user->$fullname_field : '') : $user->name;

  // Generate random password for G2 if user is blocked
  $pass = ($user->status) ? $user->pass : user_password(20);

102
  switch ($action) {
103 104 105 106 107
    case 'username':
      $ret = GalleryEmbed::updateUser($user->uid,
              array('username' => $user->name,
                    'fullname' => $fullname,
                    'email' => $user->mail,
108
                    'language' => gallery_get_language('', $user),
109 110 111 112 113 114 115
                    'hashedpassword' => $pass,
                    'hashmethod' => 'md5'));
      if ($ret) {
        gallery_error(t('Error updating Gallery user (username changed)'), $ret);
        return FALSE;
      }
      break;
116
    case 'create' :
117 118 119
    case 'update' :
      // Get map state of the user
      list($g2_user_state, $g2_user, $ret) = gallery_user_map_state($user);
120
      if ($ret) {
121 122
        gallery_error(t('Error determining user map state'), $ret);
        return FALSE;
123
      }
124 125
      
      // Complete user mapping
126
      switch ($g2_user_state) {
127 128 129
        case GALLERY_MAP_USER_EXISTS_BUT_NEEDS_MAPPING:
          // create map entry for the user
          $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->id, 'GalleryUser');
130
          if ($ret) {
131 132 133 134 135
            gallery_error(t('Error creating map entry (ExternlIdMapEntry)'), $ret);
            return FALSE;
          }
        case GALLERY_MAP_USER_EXISTS:
          // Update user (Drupal -> G2)
136 137 138 139
          $ret = GalleryEmbed::updateUser($user->uid,
                  array('username' => $user->name,
                        'fullname' => $fullname,
                        'email' => $user->mail,
140
                        'language' => gallery_get_language('', $user),
141 142 143
                        'hashedpassword' => $pass,
                        'hashmethod' => 'md5'));
          if ($ret) {
144 145
            gallery_error(t('Error updating Gallery user'), $ret);
            return FALSE;
146 147
          }
          break;
148 149 150
        case GALLERY_MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED:
          // Remove mapping for non-existing user
          // (also happens if gallery_user_modify() is called with a changed username)
151 152
          $ret = GalleryCoreApi::removeMapEntry('ExternalIdMap', array('externalId' => $user->uid, 'entityType' => 'GalleryUser'));
          if ($ret) {
153 154 155 156 157 158 159 160
            gallery_error(t('Error removing map entry (ExternlIdMapEntry)'), $ret);
            return FALSE;
          }
        case GALLERY_MAP_USER_DOES_NOT_EXIST:
          // Create new user
          if (!$user->uid)
            return FALSE;
          $ret = GalleryEmbed::createUser($user->uid,
161 162 163
                  array('username' => $user->name,
                        'email' => $user->mail,
                        'fullname' => $fullname,
164
                        'language' => gallery_get_language('', $user),
165 166 167
                        'hashedpassword' => $pass,
                        'hashmethod' => 'md5'));
          if ($ret) {
168 169 170 171 172 173 174
            gallery_error(t('Error creating Gallery user'), $ret);
            return FALSE;
          }
          list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
          if ($ret) {
            gallery_error(t('Error loading newly created Gallery user'), $ret);
            return FALSE;
175 176 177
          }
          break;
      }
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
      // Update group info
      _gallery_groups_user($user, $groups);
      // Admin role mapping
      $admin_role = variable_get('gallery_user_admin_role', 0);
      if (($admin_role && in_array($admin_role, array_keys($user->roles))) || ($user->uid == 1)) {
        // Get G2 admin group id
        list($ret, $g2_admin_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
        if ($ret) {
          gallery_error(t('Error getting \'adminGroup\' id'), $ret);
          return FALSE;
        }
        // Add user to admin group
        $ret = GalleryCoreApi::addUserToGroup($g2_user->id, $g2_admin_gid);
        if ($ret) {
          gallery_error(t('Error adding user to Gallery group (:gid)',
            array(':gid' => $g2_admin_gid)), $ret);
          return FALSE;
        }
      }
      break;
    case 'delete' :
      $ret = GalleryEmbed::deleteUser($user->uid);
200
      if ($ret) {
201 202
        gallery_error(t('Error deleting Gallery user'), $ret);
        return FALSE;
203
      }
204
      break;
205
  }
206 207 208 209 210 211 212
  
  // Set the 'locked' property for the user
  if (variable_get('gallery_user_locked', 0) && ($action != 'delete') && ($user->uid > 1)) {
    list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
    if ($ret) {
      gallery_error(t('Error loading Gallery user'), $ret);
      return FALSE;
213
    }
214 215 216 217 218
    if (!$g2_user->locked) {
      list($ret, $lock_id) = GalleryCoreApi::acquireWriteLock($g2_user->id);
      if ($ret) {
        gallery_error(t('Error acquiring write lock'), $ret);
        return FALSE;
219
      }
220 221 222 223
      $g2_user->setLocked(TRUE);
      if ($g2_user->save()) {
        gallery_error(t('Locking user account failed'), $ret);
        return FALSE;
224
      }
225
    }
226
  }
227 228 229

  GalleryEmbed::done();
  return TRUE;
230 231
}

232 233 234
/**
 * Function _gallery_user_sync().
 * (sync user info for $uid)
235
 */
236 237 238 239
function _gallery_user_sync($uid) {
  $user = user_load(array('uid' => $uid));
  gallery_user_modify($user, 'update', TRUE);
}
240 241

/**
242 243
 * Function gallery_user_view().
 * (view Gallery user details for a specific user)
244
 */
245 246
function gallery_user_view(&$user) {
  if (variable_get('gallery_user_profile_hide', 0) || !_gallery_init(TRUE)) {
247 248
    return;
  }
249 250 251 252 253 254
  
  // Profile section title
  $user->content['gallery2'] = array(
    '#type' => 'user_profile_category',
    '#title' => t('Gallery2')
  );
255 256
  // User album status
  if ($useralbum = gallery_user_useralbum($user->uid)) {
257 258 259 260
    $user->content['gallery2']['useralbum_link'] = array(
      '#type' => 'user_profile_item',
      '#value' => l(t('Album: @username', array('@username' => $user->name)), $useralbum)
    );
261
  }
262
  else {
263 264 265 266
    $user->content['gallery2']['useralbum_link'] = array(
      '#type' => 'user_profile_item',
      '#value' => t('User has not created an album yet')
    );
267
  }
268 269 270
  // Sync/Map status info
  $g2_userinfo = gallery_user_map_info($user);
  if (($g2_userinfo['status']) && (user_access('administer users'))) {
271 272 273 274
    $user->content['gallery2']['user_sync'] = array(
      '#type' => 'user_profile_item',
      '#title' => t('Gallery2-Drupal Sync Status'),
      '#value' => implode(',<br />', gallery_user_map_info_status($g2_userinfo['status']))
275
    );
276
  }
277 278
  
  GalleryEmbed::done();
279 280 281
}

/**
282 283
 * Function gallery_user_useralbum().
 * (create link to user album)
284
 */
285 286 287
function gallery_user_useralbum($uid = NULL, $link = TRUE) {
  if (!_gallery_init(TRUE)) {
    return FALSE;
288
  }
289
  global $user;
290 291
  $uid = isset($uid) ? $uid : $user->uid;
  $g2_user = _gallery_user_map($uid, TRUE);
292 293 294
  // User album status
  if ($g2_user && (gallery_single_plugin_status('useralbum') == GALLERY_PLUGIN_ENABLED)) {
    // Fetch user album id
295
    list($ret, $album_id) = GalleryCoreApi::getPluginParameter('module', 'useralbum', 'albumId', $g2_user[$uid]);
296 297 298 299 300 301 302 303
    if ($ret) {
      gallery_error(t('Error fetching user album id'), $ret);
      return FALSE;
    }
    // Generate link to user album
    if (is_numeric($album_id) && $album_id > 0) {
      return $link ? gallery_generate_url(array('itemId' => $album_id), FALSE) : $album_id;
    }
304
  }
305 306
  
  return FALSE;
307 308 309
}

/**
310 311
 * Function gallery_user_map_info().
 * (get info about user map status)
312
 */
313 314 315
function gallery_user_map_info($user, $noerror_status = TRUE) {
  $g2_userinfo = array('g2_id' => -1, 'status' => array());
  // User map entry
316 317
  $ret = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
  if ($ret && !($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
318
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_MISSING;
319 320
    return $g2_userinfo;
  }
321
  // But user not available
322 323
  list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
  if ($ret) {
324
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_MISSING;
325 326
    return $g2_userinfo;
  }
327
  // Username
328
  $g2_userinfo['g2_id'] = $g2_user->id;
329 330 331 332 333 334 335 336
  if ($g2_user->userName != $user->name) {
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_USERNAME;
  }
  // Fullname
  if (module_exists('profile') && variable_get('gallery_use_fullname', 0)) {
    $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
    $fullname_result = db_query("SELECT v.value FROM {profile_values} v INNER JOIN {profile_fields} f ON v.fid = f.fid AND v.uid = %d WHERE f.name = '%s'", $user->uid, $fullname_field);
    $fullname = db_fetch_object($fullname_result);
337
    $fullname = $fullname->value;
338 339 340 341 342
    if ($g2_user->fullName != $fullname) {
      $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_FULLNAME;
    }
    elseif (!$fullname) {
      $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_FULLNAME_MISSING;
343 344
    }
  }
345 346 347
  // Email adress
  if ($g2_user->email != $user->mail) {
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_EMAIL;
348
  }
349 350 351 352 353 354
  // Password
  if ($user->status && ($g2_user->hashedPassword != $user->pass)) {
    if (strlen($g2_user->hashedPassword) != strlen($user->pass)) {
      $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_HASHMETHOD;
    }
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_PASSWORD;
355
  }
356 357 358
  // Roles/Groups
  if (!gallery_groups_map_info($g2_user, $user)) {
    $g2_userinfo['status'][] = GALLERY_USERINFO_ERROR_GROUPS;
359
  }
360 361 362
  // Overall sync status
  if ($noerror_status && !count($g2_userinfo['status'])) {
    $g2_userinfo['status'][] = GALLERY_USERINFO_NOERROR;
363
  }
364
  
365 366
  return $g2_userinfo;
}
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449

/**
 * Function gallery_user_map_info_status().
 * (get string representation of the use map status)
 */
function gallery_user_map_info_status($info = array(), $format = TRUE) {
  $info_map = array(
    GALLERY_USERINFO_NOERROR                    => t('OK'),
    GALLERY_USERINFO_ERROR                      => t('Any Error'),
    GALLERY_USERINFO_ERROR_MISSING              => t('Missing from G2'),
    GALLERY_USERINFO_ERROR_USERNAME             => t('Different Usernames'),
    GALLERY_USERINFO_ERROR_FULLNAME             => t('Different Full Names'),
    GALLERY_USERINFO_ERROR_FULLNAME_MISSING     => t('G2 Full Name missing'),
    GALLERY_USERINFO_ERROR_EMAIL                => t('Different E-Mails'),
    GALLERY_USERINFO_ERROR_PASSWORD             => t('Different Passwords'),
    GALLERY_USERINFO_ERROR_HASHMETHOD           => t('Imported/Different hash method'),
    GALLERY_USERINFO_ERROR_GROUPS               => t('Roles <> Groups')
  );
  
  if ($format) {
    $status = array();
    if (!count($info)) {
      $info[] = GALLERY_USERINFO_NOERROR;
    }
    foreach ($info as $key => $value) {
      $status[] = $info_map[$value];
    }
    return $status;
  }
  
  return $info_map;
}

/**
 * Function gallery_user_map_state().
 * (get state of user mapping)
 */
function gallery_user_map_state($user) {
  // See if user already exists in G2
  list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($user->name);
  if (!$ret) {
    // User is in G2, so map the user if needed
    $ret2 = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
    if ($ret2) {
      if ($ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
        return array(GALLERY_MAP_USER_EXISTS_BUT_NEEDS_MAPPING, $g2_user, NULL);
      }
      else {
        // Some other error
        return array(GALLERY_MAP_UNKNOWN, $g2_user, $ret2);
      }
    }
    else {
        return array(GALLERY_MAP_USER_EXISTS, $g2_user, NULL);
    }
  }
  elseif ($ret->getErrorCode() & ERROR_MISSING_OBJECT) {
    // User does not yet exist in G2
    // Check if the externalID was mapped (it should not be)
    $ret2 = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
    if ($ret2) {
      if ($ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
        return array(GALLERY_MAP_USER_DOES_NOT_EXIST, $g2_user, NULL);
      }
      else {
        // Some other error
        return array(GALLERY_MAP_UNKNOWN, $g2_user, $ret2);
      }
    }
    else {
      // User is mapped
      return array(GALLERY_MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED, $g2_user, NULL);
    }
  }
  else {
    return array(NULL, $g2_user, $ret);
  }
}

/**
 * Function _gallery_user_import().
 * (import Gallery users into Drupal)
 */
450
function _gallery_user_import($g2_users, &$messages) {
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
  $resolve_conflict = variable_get('gallery_user_import_conflict', array());
  // Anonymous user id
  list($ret, $guest) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.anonymousUser');
  if (!$ret) {
    unset($g2_users[$guest]);
  }
  if (($g2_groups_map = _gallery_groups_map()) === FALSE) {
    return FALSE;
  }
  if (($g2_extIdMap = _gallery_user_map(array_keys($g2_users))) === FALSE) {
    return FALSE;
  }
  gallery_debug($g2_users, t('G2 Users'));
  gallery_debug($g2_extIdMap, t('G2 ExternalIdMap'));
  // Iterate over G2 users
  foreach ($g2_users as $g2_id => $g2_username) {
    $new_user = !array_key_exists($g2_id, $g2_extIdMap);
    list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($g2_username);
    if ($ret) {
      gallery_error(t('Error fetching user by username (:name)',
        array(':name' => $g2_username)), $ret);
      return FALSE;
    }
    // Collect user details and validate the values (name, mail, ...)
    $values = array();
    $values['name'] = $g2_user->userName;
    if ($error = user_validate_name($values['name'])) {
      $messages[] = t('G2 User Import (uid: :uid, name: \':name\'): !error',
        array(':uid' => $g2_id, ':name' => $values['name'], '!error' => $error));
      continue;
    }
    $values['fullname'] = $g2_user->fullName;
    $values['pass'] = user_password(20);
    $password_hash = $g2_user->hashedPassword;
    $values['mail'] = $g2_user->email;
    if ($error = user_validate_mail($values['mail'])) {
      if ($resolve_conflict[GALLERY_IMPORT_CONFLICT_INVALID]) {
        _gallery_user_resolve_mail($values['mail'], $values['name'], $messages);
        $error = user_validate_mail($values['mail']) ? $error : FALSE;
      }
      if ($error) {
        $messages[] = t('G2 User Import (uid: :uid, name: \':name\'): !error',
          array(':uid' => $g2_id, ':name' => $values['name'], '!error' => $error));
        continue;
      }
    }
497
    else if ($new_user && db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE uid != 0 AND LOWER(mail) = LOWER('%s')", $values['mail'])) > 0) {
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
      $error = TRUE;
      if ($resolve_conflict[GALLERY_IMPORT_CONFLICT_DUPLICATE]) {
        _gallery_user_resolve_mail($values['mail'], $values['name'], $messages);
        $error = FALSE;
      }
      if ($error) {
        $messages[] = t('G2 User Import (uid: :uid, name: \':name\'): The e-mail address :mail is already registered.',
          array(':uid' => $g2_id, ':name' => $values['name'], ':mail' => $values['mail']));
        continue;
      }
    }
    $values['language'] = $g2_user->language;
    $values['created'] = $g2_user->creationTimestamp;
    $values['roles'] = array();
    list($ret, $g2_groups) = GalleryCoreApi::fetchGroupsForUser($g2_user->id);
    if ($ret) {
      gallery_error(t('Error fetching groups for user (uid: :uid)',
        array(':uid' => $g2_id)), $ret);
      return FALSE;
    }
    foreach ($g2_groups as $g2_gid => $g2_groupname) {
      if (isset($g2_groups_map[$g2_gid])) {
        $values['roles'][$g2_groups_map[$g2_gid]] = $g2_groupname;
      }
    }
    // Is the user blocked in G2
    list($ret, $g2_user_blocked) = GalleryCoreApi::isDisabledUsername($g2_username);
    if ($ret) {
      gallery_error(t('Error calling isDisabledUsername() for \':name\'',
        array(':name' => $g2_username)), $ret);
      return FALSE;
    }
    $values['status'] = !$g2_user_blocked;
    // Create new Drupal user (this will also override the G2 user
    //  during hook_user, but there is no 'clean' way to avoid this)
    if ($new_user) {
      $values['notify'] = FALSE;
      if (!($user = user_save('', $values))) {
        $messages[] = t('Error creating Drupal user for G2 user (uid: :uid)',
          array(':uid' => $g2_id));
        continue;
      }
    }
    else {
      $user = new stdClass();
      $user->uid = $g2_extIdMap[$g2_id];
    }
    // Override user details if requested (or for new users)
    if ($user->uid && ($new_user || variable_get('gallery_user_import_override', 0))) {
      // Fullname support
      if (module_exists('profile') && variable_get('gallery_use_fullname', 0)) {
        $fullname_category = variable_get('gallery_profile_fullname_category', 'Personal Information');
        $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
        $values[$fullname_field] = $values['fullname'];
        profile_save_profile($values, $user, $fullname_category);
      }
      // Do we have a md5 hash (unsalted hash)?
      if (strlen($password_hash) == 32) {
        db_query("UPDATE {users} SET pass = '%s' WHERE uid = %d", $password_hash, $user->uid);
        unset($values['pass']);
      }
      // Update Drupal user with G2 user details (invokes hook_user)
      user_save(user_load(array('uid' => $user->uid)), $values);
      // Override/Restore password in G2 (in case we have a salted G2 hash)
      // (Drupal hash will remain a dummy and user is authenticated in hook_auth against G2 directly)
      if (strlen($password_hash) > 32) {
        $ret = GalleryEmbed::updateUser($user->uid, array('hashedpassword' => $password_hash, 'hashmethod' => 'md5'));
        if ($ret) {
          gallery_error(t('Error updating Gallery user (password)'), $ret);
          return FALSE;
        }
      }
    }
  }
  
  return TRUE;
}

/**
 * Function _gallery_user_resolve_mail()
 */
function _gallery_user_resolve_mail(&$mail, $username, &$messages) {
  // Replace all invalid chars in the username
  $invalid_search = array(' ', '!', '#', '$', '%', '&', '*', '+', '/', '=', '?', '`', '|', '{', '}', '~', '\'');
  $invalid_replace = array_fill(0, count($invalid_search), '_');
  $user = str_replace($invalid_search, $invalid_replace, $username);
  // Generate a new mail address using a simple 'username_#@drupaldomain' naming schema
  // (=> username@drupaldomain, username_1@drupaldomain, username_2@drupaldomain, ...)
  $i = 0;
  do {
    $newmail = $user . (($i > 0) ? ('_'. $i) : '') .'@'. $_SERVER['HTTP_HOST'];
589
    $error = (db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE uid != 0 AND LOWER(mail) = LOWER('%s')", $newmail)) > 0);
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
  } while ($error && $i++ < 10);
  // Do we have a new mail address?
  if (!$error) {
    $messages[] = t('G2 User Import (name: \':name\'): e-mail address :oldmail changed to :newmail.',
      array(':name' => $username, ':oldmail' => $mail, ':newmail' => $newmail));
    $mail = $newmail;
  }
}

/**
 * Function _gallery_user_map().
 * (fetch 'GalleryUser' entries from G2 'ExternalIdMap')
 */
function _gallery_user_map($ids = array(), $inverse = FALSE) {
  // g2Id => externalId (default)
  $ids = is_array($ids) ? $ids : array($ids);
  $match = array('entityType' => 'GalleryUser');
  if (count($ids) > 0) {
    if ($inverse) {
      $match['externalId'] = $ids;
    }
    else {
      $match['entityId'] = $ids;
    }
  }
  // Fetch the map entries
  list($ret, $resultMap) = GalleryCoreApi::getMapEntry('ExternalIdMap', array('externalId', 'entityId'), $match);
  if ($ret) {
    gallery_error(t('Error fetching \'GalleryUser\' entries from \'ExternalIdMap\''), $ret);
    return FALSE;
  }
  // Iterate over the results
  $g2_extIdMap = array();
  while (($row = $resultMap->nextResult()) !== FALSE) {
    $g2_extIdMap[($inverse ? $row[0] : $row[1])] = ($inverse ? $row[1] : $row[0]);
  }
  
  return $g2_extIdMap;
}

/**
 * Function _gallery_user_drupal_users().
 * (fetch all existing Drupal users (uid => username))
 */
function _gallery_user_drupal_users() {
  $users = array();
  $result = db_query("SELECT uid, name FROM {users} WHERE uid > 0");
  while ($user = db_fetch_object($result)) {
    $users[$user->uid] = $user->name;
  }
  
  return $users;
}