Skip to content
gallery_user.inc 20.3 KiB
Newer Older
<?php
// $Id$

/**
 * gallery.module : gallery_user.inc
 * User Functions (insert, update, delete, view, details, ...)
 
define(G2MAP_UNKNOWN,                             0);
define(G2MAP_USER_EXISTS,                         1);
define(G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING,       2);
define(G2MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED,   3);
define(G2MAP_USER_DOES_NOT_EXIST,                 4);
define(G2USERINFO_NOERROR,                        1);
define(G2USERINFO_ERROR,                          2);
define(G2USERINFO_ERROR_MISSING,                  3);
define(G2USERINFO_ERROR_USERNAME,                 4);
define(G2USERINFO_ERROR_FULLNAME,                 5);
define(G2USERINFO_ERROR_FULLNAME_MISSING,         6);
define(G2USERINFO_ERROR_FULLNAME_INCORRECT,       7);
define(G2USERINFO_ERROR_EMAIL,                    8);
define(G2USERINFO_ERROR_PASSWORD,                 9);
define(G2USERINFO_ERROR_GROUPS,                  10);
kiz_0987's avatar
kiz_0987 committed

require_once(drupal_get_path('module', 'gallery') .'/gallery_groups.inc');
function gallery_user_insert(&$edit, $user) {
    $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
    $user->status = isset($edit['status']) ? $edit['status'] : TRUE;
    gallery_user_modify($user, 'create');
}

/**
 * Update a user with new information
 */
function gallery_user_update(&$edit, $user) {
  $user->language = isset($edit['language']) ? $edit['language'] : gallery_get_language($user);
  $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;
  // 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;
    gallery_user_modify($user, 'username');
  }
  else {
    gallery_user_modify($user, 'update', TRUE);
}

/**
 * Delete the user from the Gallery 
 */ 
function gallery_user_delete($user) {
  gallery_user_modify($user, 'delete');
 * Modify (create/update/delete) a user
function gallery_user_modify($user, $action = 'create', $groups = FALSE, $vars = NULL) {
  if (!_gallery_init(TRUE, $vars)) {
  // 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);

  switch ($action) {
    case 'username':
      $ret = GalleryEmbed::updateUser($user->uid,
              array('username' => $user->name,
                    'fullname' => $fullname,
                    'email' => $user->mail,
                    'language' => gallery_get_language($user),
                    'hashedpassword' => $pass,
                    'hashmethod' => 'md5'));
      if ($ret) {
        gallery_error(t('Error updating Gallery user (username changed)'), $ret);
        return FALSE;
      }
      break;
      list($g2_user_state, $g2_user, $ret) = gallery_user_map_state($user);
        gallery_error(t('Error determining user map state'), $ret);
        return FALSE;
        case G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING:
          // create map entry for the user
          $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->id, 'GalleryUser');
            gallery_error(t('Error creating map entry (ExternlIdMapEntry)'), $ret);
            return FALSE;
          }
        case G2MAP_USER_EXISTS:
          // Update user (Drupal -> G2)
          $ret = GalleryEmbed::updateUser($user->uid,
                  array('username' => $user->name,
                        'fullname' => $fullname,
                        'email' => $user->mail,
                        'language' => gallery_get_language($user),
                        'hashedpassword' => $pass,
                        'hashmethod' => 'md5'));
          if ($ret) {
            gallery_error(t('Error updating Gallery user'), $ret);
            return FALSE;
        case G2MAP_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)
          $ret = GalleryCoreApi::removeMapEntry('ExternalIdMap', array('externalId' => $user->uid, 'entityType' => 'GalleryUser'));
          if ($ret) {
            gallery_error(t('Error removing map entry (ExternlIdMapEntry)'), $ret);
            return FALSE;
          }
kiz_0987's avatar
kiz_0987 committed
        case G2MAP_USER_DOES_NOT_EXIST:
          if (!$user->uid)
            return FALSE;
          $ret = GalleryEmbed::createUser($user->uid,
                  array('username' => $user->name,
                        'email' => $user->mail,
                        'fullname' => $fullname,
                        'language' => gallery_get_language($user),
                        'hashedpassword' => $pass,
                        'hashmethod' => 'md5'));
          if ($ret) {
            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);
      _gallery_groups_user($user, $groups);
      $admin_role = variable_get('gallery_user_admin_role', 0);
      if (($admin_role && in_array($admin_role, array_keys($user->roles))) || ($user->uid == 1)) {
        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);
        gallery_error(t('Error deleting Gallery user'), $ret);
        return FALSE;
  
  // 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;
    }
    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;
      }
      $g2_user->setLocked(TRUE);
      if ($g2_user->save()) {
        gallery_error(t('Locking user account failed'), $ret);
        return FALSE;
      }
  GalleryEmbed::done();
  return TRUE;
function _gallery_user_sync($uid) {
  $user = user_load(array('uid' => $uid));
  gallery_user_modify($user, 'update', TRUE);

/**
 * View Gallery user details for a specific user
 */
function gallery_user_view($user) {
  if (variable_get('gallery_user_hide_profile', 0) || !_gallery_init(TRUE)) {
  if ($useralbum = gallery_user_useralbum($user->uid)) {
    $form['gallery_view_user_album'] = array(
      'value' => l(t('User Album'), $useralbum),
      'class' => 'send-message');
  }
  else {
    $form['gallery_view_user_album'] = array(
      'value' => t('User has not created an album yet'),
      'class' => 'send-message');
  }
  // Sync/Map status info
  $g2_userinfo = gallery_user_map_info($user);
  if (($g2_userinfo['status']) && (user_access('administer users'))) {
    $form['gallery_view_user'] = array(
      'title' => t('Gallery2-Drupal Sync Status'), 
      'value' => implode(',<br />', gallery_user_map_info_status($g2_userinfo['status']))
    );
  }
  
  GalleryEmbed::done();
  if (!empty($form)) {
    return array(t('Gallery2') => $form);
  }
}

/**
 * Create link to user album
 */
function gallery_user_useralbum($uid = NULL, $link = TRUE) {
  if (!_gallery_init(TRUE)) {
    return FALSE;
  }
  global $user;
  list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId(isset($uid) ? $uid : $user->uid, 'GalleryUser');
  if ($ret) {
    if (!($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
      gallery_error(t('Error loading Gallery user'), $ret);
  // User album status
  if ($g2_user && (gallery_single_plugin_status('useralbum') == GALLERY_PLUGIN_ENABLED)) {
    // Fetch user album id
    list($ret, $album_id) = GalleryCoreApi::getPluginParameter('module', 'useralbum', 'albumId', $g2_user->id);
      gallery_error(t('Error fetching user album id'), $ret);
    // Generate link to user album
    if (is_numeric($album_id) && $album_id > 0) {
      return $link ? gallery_generate_url(array('view' => 'core.ShowItem', 'itemId' => $album_id), FALSE) : $album_id;
 * Get info about user map status
function gallery_user_map_info($user, $noerror_status = TRUE) {
  $g2_userinfo = array('g2_id' => -1, 'status' => array());
  $ret = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
  if ($ret && !($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
    $g2_userinfo['status'][] = G2USERINFO_ERROR_MISSING;
    return $g2_userinfo;
  }
  list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
  if ($ret) {
    $g2_userinfo['status'][] = G2USERINFO_ERROR_MISSING;
    return $g2_userinfo;
  }
  $g2_userinfo['g2_id'] = $g2_user->id;
  if ($g2_user->userName != $user->name) {
    $g2_userinfo['status'][] = G2USERINFO_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);
    $fullname = $fullname->value;
    if ($g2_user->fullName != $fullname) {
      $g2_userinfo['status'][] = G2USERINFO_ERROR_FULLNAME;
kiz_0987's avatar
kiz_0987 committed
    elseif (!$fullname) {
      $g2_userinfo['status'][] = G2USERINFO_ERROR_FULLNAME_MISSING;
    if ($g2_user->fullName != $user->name) {
      $g2_userinfo['status'][] = G2USERINFO_ERROR_FULLNAME_INCORRECT;
  // Email adress
  if ($g2_user->email != $user->mail) {
    $g2_userinfo['status'][] = G2USERINFO_ERROR_EMAIL;
  if ($user->status && ($g2_user->hashedPassword != $user->pass)) {
    $g2_userinfo['status'][] = G2USERINFO_ERROR_PASSWORD;
  }
  // Roles/Groups
  if (!gallery_groups_map_info($g2_user, $user)) {
    $g2_userinfo['status'][] = G2USERINFO_ERROR_GROUPS;
  if ($noerror_status && !count($g2_userinfo['status'])) {
    $g2_userinfo['status'][] = G2USERINFO_NOERROR;
kiz_0987's avatar
kiz_0987 committed
/**
 * Get string representation of the use map status
 */
function gallery_user_map_info_status($info = array(), $format = TRUE) {
kiz_0987's avatar
kiz_0987 committed
  $info_map = array(
    G2USERINFO_NOERROR                    => t('OK'),
    G2USERINFO_ERROR                      => t('Any Error'),
    G2USERINFO_ERROR_MISSING              => t('Missing from G2'),
    G2USERINFO_ERROR_USERNAME             => t('Different Usernames'),
    G2USERINFO_ERROR_FULLNAME             => t('Different Full Names'),
    G2USERINFO_ERROR_FULLNAME_MISSING     => t('G2 Full Name missing'),
    G2USERINFO_ERROR_FULLNAME_INCORRECT   => t('G2 Full Name incorrect'),
    G2USERINFO_ERROR_EMAIL                => t('Different E-Mails'),
    G2USERINFO_ERROR_PASSWORD             => t('Different Passwords'),
    G2USERINFO_ERROR_GROUPS               => t('Roles <> Groups')
kiz_0987's avatar
kiz_0987 committed
    $status = array();
    if (!count($info)) {
      $info[] = G2USERINFO_NOERROR;
    }
kiz_0987's avatar
kiz_0987 committed
    foreach ($info as $key => $value) {
      $status[] = $info_map[$value];
    }
    return $status;
  }
  
  return $info_map;
}

/**
 * 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);
    // 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(G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING, $g2_user, NULL);
      }
      else {
        return array(G2MAP_UNKNOWN, $g2_user, $ret2);
      }
    }
    else {
        return array(G2MAP_USER_EXISTS, $g2_user, NULL);
    }
  }
kiz_0987's avatar
kiz_0987 committed
  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(G2MAP_USER_DOES_NOT_EXIST, $g2_user, NULL);
      }
      else {
        return array(G2MAP_UNKNOWN, $g2_user, $ret2);
      }
    }
    else {
      return array(G2MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED, $g2_user, NULL);
    }
  else {
    return array(NULL, $g2_user, $ret);

/**
 * Import Gallery users into Drupal
 */
function _gallery_user_import($g2_users = array()) {
  list($ret, $guest) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.anonymousUser');
  if (!$ret) {
    unset($g2_users[$guest]);
  }
  $g2_groups_map = _gallery_groups_map();
  if (!($g2_extIdMap = _gallery_user_map(array_keys($g2_users)))) {
    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 and mail)
    $values = array();
    $values['name'] = $g2_user->userName;
    if ($error = user_validate_name($values['name'])) {
      $errors[] = 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'] = $g2_user->hashedPassword;
    $values['mail'] = $g2_user->email;
    if ($error = user_validate_mail($values['mail'])) {
      $errors[] = t('G2 User Import (uid: :uid, mail: \':mail\'): !error',
        array(':mail' => $values['mail'], ':uid' => $g2_id, '!error' => $error));
      continue;
    }
    else if ($new_user && db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != 0 AND LOWER(mail) = LOWER('%s')", $values['mail'])) > 0) {
      $errors[] = t('G2 User Import (uid: :uid): The e-mail address :mail is already registered.',
        array(':uid' => $g2_id, ':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) {
      if (!($user = user_save('', $values))) {
        $errors[] = t('Error creating Drupal user for G2 user (uid: :uid)',
          array(':uid' => $g2_id));
      $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);
      // Override password directly (needed because G2 only provides the md5 hash)
      _gallery_user_drupal_password($user->uid, $values['pass']);
      unset($values['pass']);
      // Update Drupal user with G2 user details (invokes hook_user)
      user_save(user_load(array('uid' => $user->uid)), $values);
    if (isset($_SESSION['gallery_user_progress_messages'])) {
      $_SESSION['gallery_user_progress_messages'] += $errors;
    }
    else {
      drupal_set_message(theme('item_list', $errors, t('The following invalid user items were skipped:')), 'error');
 * Override Drupal user password
function _gallery_user_drupal_password($uid, $pass) {
  db_query("UPDATE {users} SET pass = '%s' WHERE uid = %d", $pass, $uid);
 * Fetch 'GalleryUser' entries from G2 'ExternalIdMap'
 *  g2Id => externalId (default)
 */
function _gallery_user_map($ids = array(), $inverse = FALSE) {
  $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 NULL;
  }
  // 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;
}

/**
 * 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;
}