User status page filter.
[project/gallery.git] / gallery_user.inc
1 <?php
2 // $Id$
3
4 /**
5 * gallery.module : gallery_user.inc
6 * User Functions (insert, update, delete, view, details, ...)
7 */
8
9 define(G2MAP_UNKNOWN, 0);
10 define(G2MAP_USER_EXISTS, 1);
11 define(G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING, 2);
12 define(G2MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED, 3);
13 define(G2MAP_USER_DOES_NOT_EXIST, 4);
14
15 define(G2USERINFO_ERROR_OK, 1);
16 define(G2USERINFO_ERROR_MISSING, 2);
17 define(G2USERINFO_ERROR_USERNAME, 3);
18 define(G2USERINFO_ERROR_FULLNAME, 4);
19 define(G2USERINFO_ERROR_FULLNAME_MISSING, 5);
20 define(G2USERINFO_ERROR_FULLNAME_INCORRECT, 6);
21 define(G2USERINFO_ERROR_EMAIL, 7);
22 define(G2USERINFO_ERROR_PASSWORD, 8);
23 define(G2USERINFO_ERROR_BLOCKED, 9);
24
25 require_once(drupal_get_path('module', 'gallery') .'/gallery_groups.inc');
26
27 /**
28 * Insert new user
29 */
30 function gallery_user_insert(&$edit, $user) {
31 $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
32
33 gallery_user_modify($user, 'create');
34 }
35
36 /**
37 * Update a user with new information
38 */
39 function gallery_user_update(&$edit, $user) {
40 $user->language = ($edit['language']) ? $edit['language'] : gallery_get_language($user);
41 $user->pass = ($edit['pass']) ? md5($edit['pass']) : $user->pass;
42 $user->status = ($edit['status']) ? $edit['status'] : $user->status;
43 $user->mail = ($edit['mail']) ? $edit['mail'] : $user->mail;
44 $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
45
46 // fullname support
47 if (module_exists('profile') && variable_get('gallery_use_full_name', FALSE)) {
48 $fullname_field = variable_get('gallery_profile_full_name_field', 'profile_full_name');
49 $user->$fullname_field = ($edit[$fullname_field]) ? $edit[$fullname_field] : $user->$fullname_field;
50 }
51
52 // username is about to change
53 if ($namechange = $edit['name'] && ($edit['name'] != $user->name)) {
54 // make sure the original user is up to date
55 gallery_user_modify($user, 'update');
56 }
57
58 $user->name = ($edit['name']) ? $edit['name'] : $user->name;
59
60 if ($namechange) {
61 // change username
62 gallery_user_modify($user, 'username');
63 }
64 else {
65 // update user
66 gallery_user_modify($user, 'update');
67 }
68 }
69
70 /**
71 * Delete the user from the Gallery
72 */
73 function gallery_user_delete($user) {
74 gallery_user_modify($user, 'delete');
75 }
76
77 /**
78 * Modify (create/update/delete) a user
79 */
80 function gallery_user_modify($user, $action = 'create', $groups = FALSE, $vars = NULL) {
81 if (!_gallery_init(TRUE, $vars)) {
82 return FALSE;
83 }
84
85 // check for fullname support
86 $fullname_field = variable_get('gallery_profile_full_name_field', 'profile_full_name');
87 $usefullname = module_exists('profile') && variable_get('gallery_use_full_name', 0);
88 $fullname = $usefullname ? (isset($user->$fullname_field) ? $user->$fullname_field : '') : $user->name;
89
90 // generate random password for G2 if user is blocked
91 $pass = ($user->status) ? $user->pass : user_password(20);
92
93 switch ($action) {
94 case 'username':
95 $ret = GalleryEmbed::updateUser($user->uid,
96 array('username' => $user->name,
97 'fullname' => $fullname,
98 'email' => $user->mail,
99 'language' => gallery_get_language($user),
100 'hashedpassword' => $pass,
101 'hashmethod' => 'md5'));
102 if ($ret) {
103 gallery_error(t('Error updating Gallery user (username changed)'), $ret);
104 return FALSE;
105 }
106 break;
107 case 'create' :
108 case 'update' :
109 // get map state of the user
110 list($g2_user_state, $g2_user, $ret) = gallery_user_map_state($user);
111 if ($ret) {
112 gallery_error(t('Error determining user map state'), $ret);
113 return FALSE;
114 }
115
116 // complete user mapping
117 switch ($g2_user_state) {
118 case G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING:
119 // create map entry for the user
120 $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->getId(), 'GalleryUser');
121 if ($ret) {
122 gallery_error(t('Error creating map entry (ExternlIdMapEntry)'), $ret);
123 return FALSE;
124 }
125 case G2MAP_USER_EXISTS:
126 // update user (Drupal -> G2)
127 $ret = GalleryEmbed::updateUser($user->uid,
128 array('username' => $user->name,
129 'fullname' => $fullname,
130 'email' => $user->mail,
131 'language' => gallery_get_language($user),
132 'hashedpassword' => $pass,
133 'hashmethod' => 'md5'));
134 if ($ret) {
135 gallery_error(t('Error updating Gallery user'), $ret);
136 return FALSE;
137 }
138 break;
139 case G2MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED:
140 // remove mapping for non-existing user
141 // (also happens if gallery_user_modify() is called with a changed username)
142 $ret = GalleryCoreApi::removeMapEntry('ExternalIdMap', array('externalId' => $user->uid, 'entityType' => 'GalleryUser'));
143 if ($ret) {
144 gallery_error(t('Error removing map entry (ExternlIdMapEntry)'), $ret);
145 return FALSE;
146 }
147 case G2MAP_USER_DOES_NOT_EXIST:
148 // create new user
149 if (!$user->uid)
150 return FALSE;
151 $ret = GalleryEmbed::createUser($user->uid,
152 array('username' => $user->name,
153 'email' => $user->mail,
154 'fullname' => $fullname,
155 'language' => gallery_get_language($user),
156 'hashedpassword' => $pass,
157 'hashmethod' => 'md5'));
158 if ($ret) {
159 gallery_error(t('Error creating Gallery user'), $ret);
160 return FALSE;
161 }
162 list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
163 if ($ret) {
164 gallery_error(t('Error loading Gallery user'), $ret);
165 return FALSE;
166 }
167 break;
168 }
169 // update group info
170 _gallery_groups_user($user, $groups);
171 // admin role mapping
172 $admin_role = variable_get('gallery_user_admin_role', 0);
173 if (($admin_role && in_array($admin_role, array_keys($user->roles))) || ($user->uid == 1)) {
174 // get G2 admin group id
175 list($ret, $g2_admin_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
176 if ($ret) {
177 gallery_error(t('Error getting \'adminGroup\' id'), $ret);
178 return FALSE;
179 }
180 // add user to admin group
181 $ret = GalleryCoreApi::addUserToGroup($g2_user->getId(), $g2_admin_gid);
182 if ($ret) {
183 gallery_error(t('Error adding user to Gallery group (:gid)',
184 array(':gid' => $g2_admin_gid)), $ret);
185 return FALSE;
186 }
187 }
188 break;
189 case 'delete' :
190 $ret = GalleryEmbed::deleteUser($user->uid);
191 if ($ret) {
192 gallery_error(t('Error deleting Gallery user'), $ret);
193 return FALSE;
194 }
195 break;
196 }
197
198 GalleryEmbed::done();
199 return TRUE;
200 }
201
202 /**
203 * Sync user info for $uid
204 */
205 function _gallery_user_sync($uid) {
206 $user = user_load(array('uid' => $uid));
207 gallery_user_modify($user, 'update', TRUE);
208 }
209
210 /**
211 * View Gallery user details for a specific user
212 */
213 function gallery_user_view($user) {
214 if (variable_get('gallery_user_hide_profile', 0) || !_gallery_init(TRUE)) {
215 return;
216 }
217 // get map status info
218 $g2_userinfo = gallery_user_map_info($user);
219 // load G2 user
220 list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
221 if ($ret) {
222 if (!($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
223 gallery_error(t('Error loading Gallery user'), $ret);
224 return;
225 }
226 }
227 // fetch user album id
228 if ($g2_user) {
229 list($ret, $album_id) =
230 GalleryCoreApi::getPluginParameter('module', 'useralbum', 'albumId', $g2_user->getId());
231 if ($ret) {
232 gallery_error(t('Error fetching user album id'), $ret);
233 return;
234 }
235 }
236 // generate link to user album
237 if (!empty($album_id)) {
238 $link = gallery_generate_url(array('view' => 'core.ShowItem', 'itemId' => $album_id), FALSE);
239 $form['gallery_view_user_album'] = array(
240 'value' => l(t('User Album'), $link),
241 'class' => 'send-message');
242 }
243 else {
244 $form['gallery_view_user_album'] = array(
245 'value' => t('User has not created an album yet'),
246 'class' => 'send-message');
247 }
248 // sync status
249 if (($g2_userinfo['error']) && (user_access('administer users'))) {
250 $form['gallery_view_user'] = array(
251 'title' => t('Gallery2-Drupal Sync Status'),
252 'value' => implode(',<br />', gallery_user_map_info_status($g2_userinfo['error'])) .'<br />');
253 }
254
255 GalleryEmbed::done();
256 if (!empty($form)) {
257 return array(t('Gallery2') => $form);
258 }
259 }
260
261 /**
262 * Get info about user map status
263 */
264 function gallery_user_map_info($user) {
265 $g2_userinfo['error'] = array();
266 // user map entry
267 $ret = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
268 if ($ret && !($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
269 $g2_userinfo['g2_id'] = -1;
270 $g2_userinfo['error'][] = G2USERINFO_ERROR_MISSING;
271 $g2_userinfo['sync_ok'] = 0;
272
273 return $g2_userinfo;
274 }
275 // but user not available
276 list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
277 if ($ret) {
278 $g2_userinfo['g2_id'] = -1;
279 $g2_userinfo['error'][] = G2USERINFO_ERROR_MISSING;
280 $g2_userinfo['sync_ok'] = 0;
281
282 return $g2_userinfo;
283 }
284 // username
285 $g2_userinfo['g2_id'] = $g2_user->id;
286 if ($g2_user->getuserName() != $user->name) {
287 $g2_userinfo['error'][] = G2USERINFO_ERROR_USERNAME;
288 }
289 // fullname
290 if (module_exists('profile') && variable_get('gallery_use_full_name', 0)) {
291 $fullname_field = variable_get('gallery_profile_full_name_field', 'profile_full_name');
292 $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);
293 $fullname = db_fetch_object($fullname_result);
294 $fullname = $fullname->value;
295 if ($g2_user->getfullName() != $fullname) {
296 $g2_userinfo['error'][] = G2USERINFO_ERROR_FULLNAME;
297 }
298 elseif (!$fullname) {
299 $g2_userinfo['error'][] = G2USERINFO_ERROR_FULLNAME_MISSING;
300 }
301 }
302 else {
303 if ($g2_user->getfullName() != $user->name) {
304 $g2_userinfo['error'][] = G2USERINFO_ERROR_FULLNAME_INCORRECT;
305 }
306 }
307 // email adress
308 if ($g2_user->getemail() != $user->mail) {
309 $g2_userinfo['error'][] = G2USERINFO_ERROR_EMAIL;
310 }
311 // password
312 if ($g2_user->gethashedPassword() != $user->pass) {
313 $g2_userinfo['error'][] = ($user->status) ? G2USERINFO_ERROR_PASSWORD : G2USERINFO_ERROR_BLOCKED;
314 }
315 // overall sync status
316 $g2_userinfo['sync_ok'] = (!$g2_userinfo['error']);
317 if ($g2_userinfo['sync_ok']) {
318 $g2_userinfo['error'][] = G2USERINFO_ERROR_OK;
319 }
320
321 return $g2_userinfo;
322 }
323
324 /**
325 * Get string representation of the use map status
326 */
327 function gallery_user_map_info_status($info = array()) {
328 $info_map = array(
329 G2USERINFO_ERROR_OK => t('OK'),
330 G2USERINFO_ERROR_MISSING => t('Missing from G2'),
331 G2USERINFO_ERROR_USERNAME => t('Different Usernames'),
332 G2USERINFO_ERROR_FULLNAME => t('Different Full Names'),
333 G2USERINFO_ERROR_FULLNAME_MISSING => t('G2 Full Name missing'),
334 G2USERINFO_ERROR_FULLNAME_INCORRECT => t('G2 Full Name incorrect'),
335 G2USERINFO_ERROR_EMAIL => t('Different E-Mails'),
336 G2USERINFO_ERROR_PASSWORD => t('Different Passwords'),
337 G2USERINFO_ERROR_BLOCKED => t('Blocked User'),
338 );
339
340 if (count($info)) {
341 $status = array();
342 foreach ($info as $key => $value) {
343 $status[] = $info_map[$value];
344 }
345 return $status;
346 }
347
348 return $info_map;
349 }
350
351 /**
352 * Get state of user mapping
353 */
354 function gallery_user_map_state($user) {
355 // see if user already exists in G2
356 list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($user->name);
357 if (!$ret) {
358 // user is in G2, so map the user if needed
359 $ret2 = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
360 if ($ret2) {
361 if ($ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
362 return array(G2MAP_USER_EXISTS_BUT_NEEDS_MAPPING, $g2_user, NULL);
363 }
364 else {
365 // some other error
366 return array(G2MAP_UNKNOWN, $g2_user, $ret2);
367 }
368 }
369 else {
370 return array(G2MAP_USER_EXISTS, $g2_user, NULL);
371 }
372 }
373 elseif ($ret->getErrorCode() & ERROR_MISSING_OBJECT) {
374 // user does not yet exist in G2
375 // check if the extID was mapped (it should not be)
376 $ret2 = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
377 if ($ret2) {
378 if ($ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
379 return array(G2MAP_USER_DOES_NOT_EXIST, $g2_user, NULL);
380 }
381 else {
382 // some other error
383 return array(G2MAP_UNKNOWN, $g2_user, $ret2);
384 }
385 }
386 else {
387 // user is mapped
388 return array(G2MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED, $g2_user, NULL);
389 }
390 }
391 else {
392 // some other error
393 return array(NULL, $g2_user, $ret);
394 }
395 }
396
397 /**
398 * Import Gallery users into Drupal
399 */
400 function _gallery_user_import($g2_users = array()) {
401 // anonymous user id
402 list($ret, $guest) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.anonymousUser');
403 if (!$ret) {
404 unset($g2_users[$guest]);
405 }
406 $users = _gallery_user_drupal_users();
407 $roles_flip = array_flip(user_roles());
408 // import all missing users into Drupal
409 $g2_import_users = array_diff($g2_users, $users);
410 foreach ($g2_import_users as $g2_id => $g2_username) {
411 list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($g2_username);
412 if ($ret) {
413 gallery_error(t('Error fetching user by username (:name)',
414 array(':name' => $g2_username)), $ret);
415 return FALSE;
416 }
417 else {
418 $values['name'] = $g2_user->userName;
419 $values['pass'] = $g2_user->hashedPassword;
420 $values['mail'] = $g2_user->email;
421 $values['status'] = TRUE;
422 /**/
423 $values['roles'] = array();
424 list($ret, $g2_groups) = GalleryCoreApi::fetchGroupsForUser($g2_user->getId());
425 if ($ret) {
426 gallery_error(t('Error fetching groups for user (uid: :uid)',
427 array(':uid' => $g2_id)), $ret);
428 return array();
429 }
430 foreach ($g2_groups as $g2_gid => $g2_groupname) {
431 $rid = $roles_flip[$g2_groupname];
432 $values['roles'][$rid] = $rid;
433 }
434 unset($values['roles'][DRUPAL_ANONYMOUS_RID]);
435 /**/
436 $values['notify'] = FALSE;
437 drupal_execute('user_register', $values);
438 // override password (we only have the md5 hash)
439 if (!variable_get('gallery_user_import_override', 1)) {
440 _gallery_user_drupal_override($g2_user->userName, array('pass' => $g2_user->hashedPassword));
441 }
442 }
443 }
444 // create new mappings and override user details (if requested)
445 $users = _gallery_user_drupal_users();
446 $users = array_intersect($users, $g2_users);
447 foreach ($users as $uid => $username) {
448 if (variable_get('gallery_user_import_override', 1)) {
449 list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($username);
450 if ($ret) {
451 gallery_error(t('Error fetching user by username (:name)',
452 array(':name' => $username)), $ret);
453 return FALSE;
454 }
455 $values = array();
456 $values['pass'] = $g2_user->hashedPassword;
457 $values['mail'] = $g2_user->email;
458 $values['language'] = $g2_user->language;
459 $values['fullname'] = $g2_user->fullName;
460 _gallery_user_drupal_override($username, $values);
461 }
462 // create new mappings
463 $ret = GalleryEmbed::addExternalIdMapEntry($uid, $g2_user->getId(), 'GalleryUser');
464 if ($ret) {
465 gallery_error(t('Error creating map entry (ExternlIdMapEntry)'), $ret);
466 return FALSE;
467 }
468 }
469
470 return TRUE;
471 }
472
473 /**
474 * Override Drupal user details (mail, password, language, ...)
475 */
476 function _gallery_user_drupal_override($name, $values = array()) {
477 $user = db_fetch_object(db_query("SELECT * FROM {users} WHERE name = '%s'", $name));
478 if ($user) {
479 $user->pass = $values['pass'] ? $values['pass'] : $user->pass;
480 $user->mail = $values['mail'] ? $values['mail'] : $user->mail;
481 $user->language = $values['language'] ? $values['language'] : $user->language;
482 db_query("UPDATE {users} SET pass = '%s', mail = '%s', language = '%s' WHERE name = '%s'",
483 $user->pass, $user->mail, $user->language, $name);
484 // fullname support
485 if ($values['fullname'] && module_exists('profile') && variable_get('gallery_use_full_name', 0)) {
486 $fullname_field = variable_get('gallery_profile_full_name_field', 'profile_full_name');
487 $field_id = db_result(db_query("SELECT v.fid FROM {profile_values} v INNER JOIN {profile_fields} f ON v.fid = f.fid WHERE f.name = '%s'", $fullname_field));
488 if ($field_id) {
489 db_query("DELETE FROM {profile_values} WHERE fid = %d AND uid = %d", $field_id, $user->uid);
490 db_query("INSERT INTO {profile_values} (fid, uid, value) VALUES (%d, %d, '%s')", $field_id, $user->uid, $values['fullname']);
491 }
492 }
493 }
494 }
495
496 /**
497 * Fetch all existing Drupal users (uid => username)
498 */
499 function _gallery_user_drupal_users() {
500 $users = array();
501 $result = db_query("SELECT uid, name FROM {users} WHERE uid > 0");
502 while ($user = db_fetch_object($result)) {
503 $users[$user->uid] = $user->name;
504 }
505
506 return $users;
507 }
508
509 ?>