Removing translation directories
[project/gallery.git] / gallery_user_admin.inc
1 <?php
2
3 require_once(drupal_get_path('module', 'gallery') .'/gallery_user.inc');
4
5 /**
6 * gallery.module : gallery_user_admin.inc
7 * Gallery User Administration
8 */
9
10 define('GALLERY_BATCH_INTERVAL', 50);
11
12 /**
13 * Function _gallery_user_users().
14 * (gallery users page - view list of users)
15 */
16 function _gallery_user_users($args) {
17 // Sync the selected user
18 if ($args && is_numeric($args)) {
19 _gallery_user_sync($args);
20 drupal_goto('admin/user/gallery/users');
21 }
22
23 // Generate user status overview
24 $header = array(
25 array('data' => t('ID'), 'field' => 'u.uid', 'sort' => 'asc'),
26 array('data' => t('G2ID')),
27 array('data' => t('Username'), 'field' => 'u.name'),
28 array('data' => t('Status'), 'field' => 'u.status'),
29 array('data' => t('Sync Status')),
30 t('Operations')
31 );
32 $query = 'SELECT u.uid, u.name, u.status FROM {users} u WHERE uid != 0';
33
34 $status = array(t('blocked'), t('active'));
35 $destination = drupal_get_destination();
36 $filter = $_SESSION['gallery_user_filter'];
37
38 if (!_gallery_init(TRUE)) {
39 return '';
40 }
41 list($ret, $g2_admin) = GalleryCoreApi::isUserInSiteAdminGroup();
42 if ($ret) {
43 gallery_error(t('Error calling \'GalleryCoreApi::isUserInSiteAdminGroup\'.'), $ret);
44 }
45
46 if (isset($filter)) {
47 $result = db_query($query);
48 }
49 else {
50 $query .= tablesort_sql($header);
51 $result = pager_query($query, 50);
52 }
53
54 while ($user = db_fetch_object($result)) {
55 $g2_userinfo = gallery_user_map_info(user_load(array('uid' => $user->uid)), FALSE);
56
57 $g2_id = ($g2_userinfo['g2_id'] >= 0) ? $g2_userinfo['g2_id'] : t('N/A');
58
59 $operations = array(l(t('edit'), "user/$user->uid/edit", array(), $destination));
60
61 if ($g2_admin && ($g2_userinfo['g2_id'] > 0)) {
62 $link_url = gallery_generate_url(array('view' => 'core.SiteAdmin',
63 'subView' => 'core.AdminEditUser',
64 'userId' => $g2_userinfo['g2_id']), FALSE);
65 $operations[] = l(t('edit G2'), $link_url);
66 }
67
68 if (count($g2_userinfo['status'])) {
69 $operations[] = l(t('sync'), 'admin/user/gallery/users/sync/'. $user->uid, array(), drupal_get_destination());
70 }
71
72 if (isset($filter)) {
73 if ($filter == GALLERY_USERINFO_ERROR) {
74 if (!count($g2_userinfo['status'])) {
75 continue;
76 }
77 }
78 elseif (!in_array($filter, $g2_userinfo['status'])) {
79 continue;
80 }
81 }
82
83 $rows[] = array($user->uid,
84 $g2_id,
85 theme_username($user),
86 $status[$user->status],
87 implode(',<br />', gallery_user_map_info_status($g2_userinfo['status'])),
88 implode(' | ', $operations));
89 }
90
91 if ($filter && !count($rows)) {
92 $rows[] = array(array('data' => t('There are no users with the selected status.'), 'colspan' => '6', 'align' => 'center', 'class' => 'message'));
93 }
94
95 $output = drupal_get_form('_gallery_user_filter_form', $filter);
96 $output .= theme('table', $header, $rows);
97 $output .= theme('pager', array(), 50);
98
99 GalleryEmbed::done();
100 return $output;
101 }
102
103 /**
104 * Function _gallery_user_filter_form().
105 * (filter form for user status)
106 */
107 function _gallery_user_filter_form($filter) {
108 $form['filter'] = array(
109 '#type' => 'fieldset',
110 '#title' => t('Filter by status'),
111 '#collapsible' => TRUE,
112 '#collapsed' => !$filter,
113 );
114 $filter_options = gallery_user_map_info_status(array(), FALSE);
115 unset($filter_options[GALLERY_USERINFO_NOERROR]);
116 $form['filter']['filter_status'] = array(
117 '#type' => 'select',
118 '#title' => t('Show only users with status'),
119 '#options' => $filter_options,
120 '#default_value' => $filter,
121 );
122 $form['filter']['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Filter'));
123 if ($filter) {
124 $form['filter']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
125 }
126 $form['#submit']['_gallery_user_filter_submit'] = array();
127
128 return $form;
129 }
130
131 /**
132 * Function _gallery_user_filter_submit().
133 * (submit handler of the filter form)
134 */
135 function _gallery_user_filter_submit($form_id, $form_values) {
136 unset($_SESSION['gallery_user_filter']);
137 if ($form_values['op'] == t('Filter')) {
138 $_SESSION['gallery_user_filter'] = $form_values['filter_status'];
139 }
140 }
141
142 /**
143 * Function _gallery_user_advanced().
144 * (advanced user administration)
145 */
146 function _gallery_user_advanced() {
147 $form['advanced'] = array(
148 '#type' => 'fieldset',
149 '#title' => t('Advanced Sync (Batch operations)'),
150 '#collapsible' => FALSE,
151 '#collapsed' => FALSE,
152 );
153 $form['advanced']['gallery_user_advanced_import'] = array(
154 '#type' => 'checkbox',
155 '#title' => t('Import users from Gallery2'),
156 '#return_value' => 1,
157 '#default_value' => FALSE,
158 '#description' => t('Use this option to import users from an existing Gallery2 install into Drupal.'),
159 );
160 $form['advanced']['gallery_user_advanced_sync'] = array(
161 '#type' => 'checkbox',
162 '#title' => t('Synchronize (export) all existing users'),
163 '#return_value' => 1,
164 '#default_value' => FALSE,
165 '#description' => t('Use this option to sync all users between Drupal and Gallery2.'),
166 );
167
168 $form['advanced']['gallery_user_advanced_offline'] = array(
169 '#type' => 'checkbox',
170 '#title' => t('Switch Drupal to \'offline mode\' for operation'),
171 '#return_value' => 1,
172 '#default_value' => FALSE,
173 '#disabled' => (user_access('administer site configuration') && !variable_get('site_offline', 0)) ? FALSE : TRUE,
174 '#prefix' => '<br />',
175 );
176
177 $form['buttons']['start'] = array('#type' => 'submit', '#value' => t('Start'));
178 $form['#base'] = '_gallery_user_advanced';
179 return $form;
180 }
181
182 /**
183 * Function _gallery_user_advanced_validate().
184 */
185 function _gallery_user_advanced_validate($form_id, $form_values) {
186 if (($form_values['gallery_user_advanced_import'] + $form_values['gallery_user_advanced_sync']) < 1) {
187 form_set_error('', t('No option selected.'));
188 }
189 }
190
191 /**
192 * Function _gallery_user_advanced_submit().
193 */
194 function _gallery_user_advanced_submit($form_id, $form_values) {
195 if ($form_values['op'] == t('Start')) {
196 if ($form_values['gallery_user_progress_offline']) {
197 variable_set('site_offline', 1);
198 $_SESSION['gallery_user_progress_offline'] = TRUE;
199 }
200
201 $tasks = array();
202 if ($form_values['gallery_user_advanced_import']) {
203 $tasks[] = 'import';
204 }
205 if ($form_values['gallery_user_advanced_sync']) {
206 $tasks[] = 'sync';
207 }
208 _gallery_user_advanced_start($tasks);
209 }
210 }
211
212 /**
213 * Function _gallery_user_advanced_import().
214 */
215 function _gallery_user_advanced_import(&$position) {
216 // Get number of G2 users
217 list($ret, $total) = GalleryCoreApi::fetchUserCount();
218 if ($ret || !$total) {
219 gallery_error(t('Error getting number of G2 users'), $ret);
220 return 100;
221 }
222 // First pass
223 if (!$position) {
224 // Flush entity cache
225 gallery_flush_entity_cache();
226 // Import Gallery2 groups
227 if (variable_get('gallery_user_import_groups', 1)) {
228 _gallery_groups_import();
229 }
230 }
231 // Fetch a list of G2 users
232 list($ret, $g2_users) = GalleryCoreApi::fetchUsernames(GALLERY_BATCH_INTERVAL, $position);
233 if ($ret) {
234 gallery_error(t('Error fetching G2 usernames'), $ret);
235 return 0;
236 }
237 else {
238 if (!_gallery_user_import($g2_users)) {
239 return 0;
240 }
241 }
242 $position += GALLERY_BATCH_INTERVAL;
243
244 return ( 100 * $position ) / $total;
245 }
246
247 /**
248 * Function _gallery_user_advanced_sync().
249 */
250 function _gallery_user_advanced_sync(&$position) {
251 $total = db_fetch_object(db_query("SELECT COUNT(*) AS users FROM {users} WHERE uid > 0"));
252 if (!$total->users) {
253 return 100;
254 }
255 // Empty externalIdMap in first pass
256 if (!$position && variable_get('gallery_user_sync_remap', 0)) {
257 $ret = GalleryCoreApi::removeAllMapEntries('ExternalIdMap');
258 if ($ret) {
259 gallery_error(t('Error emptying \'ExternalIdMap\''), $ret);
260 return 0;
261 }
262 }
263 // Sync users
264 $result = db_query_range("SELECT uid FROM {users} WHERE uid > 0", $position, GALLERY_BATCH_INTERVAL);
265 while ($user = db_fetch_object($result)) {
266 if ($account = user_load(array('uid' => $user->uid))) {
267 if (!gallery_user_modify($account, 'update', !$position)) {
268 return 0;
269 }
270 }
271 }
272 $position += GALLERY_BATCH_INTERVAL;
273
274 return ( 100 * $position ) / $total->users;
275 }
276
277 /**
278 * Function _gallery_user_advanced_start().
279 */
280 function _gallery_user_advanced_start($mode, $redirect = NULL) {
281 $_SESSION['gallery_user_progress_mode'] = $mode;
282 $_SESSION['gallery_user_progress_position'] = 0;
283 $_SESSION['gallery_user_progress_messages'] = array();
284 $_SESSION['gallery_user_progress_redirect'] = $redirect;
285 drupal_goto('admin/user/gallery/advanced_progress');
286 }
287
288 /**
289 * Function _gallery_user_advanced_progress().
290 */
291 function _gallery_user_advanced_progress() {
292 $mode = $_SESSION['gallery_user_progress_mode'];
293 $position = $_SESSION['gallery_user_progress_position'];
294 $messages = $_SESSION['gallery_user_progress_messages'];
295 $redirect = $_SESSION['gallery_user_progress_redirect'];
296 if ($_SERVER['REQUEST_METHOD'] == 'GET') {
297 if (!_gallery_init(TRUE, NULL, FALSE)) {
298 $percent = 0;
299 }
300 else {
301 switch (reset($mode)) {
302 case 'import':
303 $status = t('Importing Gallery2 users into Drupal ...');
304 $percent = _gallery_user_advanced_import($position);
305 break;
306 case 'sync':
307 $status = t('Synchronizing Drupal and Gallery2 users ...');
308 $percent = _gallery_user_advanced_sync($position);
309 break;
310 default:
311 $status = t('Performing batch operation ...');
312 $percent = $position++;
313 }
314 GalleryEmbed::done();
315 }
316 // Operation finished or error occured
317 if ($percent >= 100 || !$percent) {
318 array_shift($mode);
319 if (count($mode) && $percent) {
320 _gallery_user_advanced_start($mode, $redirect);
321 }
322 if ($_SESSION['gallery_user_progress_offline']) {
323 variable_set('site_offline', 0);
324 unset($_SESSION['gallery_user_progress_offline']);
325 }
326 if (count($_SESSION['gallery_user_progress_messages'])) {
327 drupal_set_message(theme('item_list', $_SESSION['gallery_user_progress_messages'], t('The following messages occured:')), 'notice');
328 drupal_set_message('<strong>'. t('Invalid user items were skipped.') .'</strong>', 'notice');
329 watchdog('gallery', theme('item_list', $_SESSION['gallery_user_progress_messages'], t('The following messages occured:')), WATCHDOG_NOTICE);
330 }
331 unset($_SESSION['gallery_user_progress_mode']);
332 unset($_SESSION['gallery_user_progress_position']);
333 unset($_SESSION['gallery_user_progress_messages']);
334 if ($percent) {
335 drupal_set_message(t('User synchronization successfully completed.'));
336 }
337 else {
338 drupal_set_message(t('User synchronization (partially) failed.'), 'error');
339 }
340 if ($redirect) {
341 unset($_SESSION['gallery_user_progress_redirect']);
342 drupal_goto($redirect);
343 }
344 drupal_goto('admin/user/gallery/advanced');
345 }
346 $_SESSION['gallery_user_progress_position'] = $position;
347 }
348
349 drupal_set_title('Drupal <> Gallery2');
350 drupal_set_html_head('<meta http-equiv="Refresh" content="0; URL='. base_path() .'index.php?q=admin/user/gallery/advanced_progress">');
351 print theme('gallery_user_progress_page', theme('progress_bar', round($percent, 1), $status), FALSE);
352 exit();
353 }
354
355 /**
356 * Theme function : theme_gallery_user_progress_page().
357 */
358 function theme_gallery_user_progress_page($content, $messages = TRUE, $partial = FALSE) {
359 drupal_set_header('Content-Type: text/html; charset=utf-8');
360 drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />');
361
362 $css = array('all' => array('module' => array('misc/maintenance.css' => FALSE, 'modules/system/system.css' => FALSE)));
363
364 $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
365 $output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
366 $output .= '<head>';
367 $output .= ' <title>'. strip_tags(drupal_get_title()) .'</title>';
368 $output .= drupal_get_html_head();
369 $output .= drupal_get_css($css);
370 $output .= drupal_get_js();
371 $output .= '</head>';
372 $output .= '<body>';
373 $output .= '<h2>'. drupal_get_title() .'</h2>';
374
375 $output .= "\n<!-- begin content -->\n";
376 $output .= $content;
377 $output .= "\n<!-- end content -->\n";
378
379 $output .= '</body></html>';
380
381 return $output;
382 }
383
384 /**
385 * Function _gallery_user_settings().
386 */
387 function _gallery_user_settings() {
388 require_once(drupal_get_path('module', 'gallery') .'/gallery_settings.inc');
389
390 $form['user'] = array(
391 '#type' => 'fieldset',
392 '#title' => t('Settings'),
393 '#collapsible' => FALSE,
394 '#collapsed' => FALSE
395 );
396
397 // Profile settings
398 $form['user']['profile'] = array(
399 '#type' => 'fieldset',
400 '#title' => t('User Profile'),
401 '#collapsible' => TRUE,
402 '#collapsed' => FALSE
403 );
404 $form['user']['profile']['gallery_user_profile_hide'] = array(
405 '#type' => 'checkbox',
406 '#title' => t('Hide Gallery2 section in profiles'),
407 '#default_value' => variable_get('gallery_user_profile_hide', 0),
408 '#description' => t('Hide the Gallery2 section (i.e. Gallery2-Drupal Sync Status) on the user profile pages.'),
409 );
410
411 // Sync settings
412 $form['user']['sync'] = array(
413 '#type' => 'fieldset',
414 '#title' => t('User Synchronization'),
415 '#collapsible' => TRUE,
416 '#collapsed' => FALSE
417 );
418
419 $roles = array(0 => t('none'));
420 $roles += user_roles(TRUE);
421 unset($roles[DRUPAL_AUTHENTICATED_RID]);
422 $form['user']['sync']['gallery_user_admin_role'] = array(
423 '#type' => 'select',
424 '#title' => t('Drupal \'admin\' role'),
425 '#default_value' => variable_get('gallery_user_admin_role', 0),
426 '#options' => $roles,
427 '#description' => t('Select the Drupal role equivalent to Gallery2\'s \'Site Admin\' group (or \'none\' to disable this
428 feature). The roles \'anonymous\' and \'authenticated\' are not available for selection.'),
429 );
430
431 $form['user']['sync']['gallery_user_locked'] = array(
432 '#type' => 'checkbox',
433 '#title' => t('Lock G2 accounts'),
434 '#default_value' => variable_get('gallery_user_locked', 0),
435 '#description' => t('Locking G2 account prevents users from changing their details (password, email, ...) in G2.'),
436 );
437
438 // Fullname settings
439 $profile_status = module_exists('profile');
440 $profile_status_str = theme('gallery_module_status_message', $profile_status);
441 $desc = t('Full names in Gallery2 can be supported by using the profile module
442 (!profile_status) with a \'Full Name\' profile field as defined below.',
443 array('!profile_status' => $profile_status_str)
444 );
445 if (!$profile_status) {
446 $desc .= t(' However the profile module is disabled, so this functionality is
447 not available and the options are disabled.');
448 }
449 $form['user']['sync']['fullname'] = array(
450 '#type' => 'fieldset',
451 '#title' => t('Full Name settings'),
452 '#collapsible' => TRUE,
453 '#collapsed' => !$profile_status,
454 '#description' => $desc,
455 );
456 if ($profile_status) {
457 $usefullname = variable_get('gallery_use_fullname', 0);
458 $form['user']['sync']['fullname']['gallery_use_fullname'] = array(
459 '#type' => 'checkbox',
460 '#title' => t('Enable Full Name support'),
461 '#return_value' => 1,
462 '#default_value' => $usefullname,
463 '#disabled' => !$profile_status,
464 '#description' => t('Use full name from profile module in Gallery2 user data. Note that
465 enabling/disabling this only updates Gallery2 user data when the
466 Drupal user is updated or if a user sync is performed.'),
467 );
468
469 if ($usefullname) {
470 $categories = array();
471 $result = db_query('SELECT DISTINCT(category) FROM {profile_fields}');
472 while ($category = db_fetch_object($result)) {
473 $categories[$category->category] = $category->category;
474 }
475 $default_category = variable_get('gallery_profile_fullname_category', 'Personal Information');
476 $form['user']['sync']['fullname']['gallery_profile_fullname_category'] = array(
477 '#type' => 'select',
478 '#title' => t('Full name profile category'),
479 '#default_value' => $default_category,
480 '#options' => $categories,
481 '#description' => t('Name of the category containing the \'Full Name\' field in profile module.'),
482 );
483 $fields = array();
484 $result = _profile_get_fields($default_category);
485 while ($field = db_fetch_object($result)) {
486 $fields[$field->name] = $field->title;
487 }
488 $form['user']['sync']['fullname']['gallery_profile_fullname_field'] = array(
489 '#type' => 'select',
490 '#title' => t('Full name profile field'),
491 '#default_value' => variable_get('gallery_profile_fullname_field', 'profile_fullname'),
492 '#options' => $fields,
493 '#description' => t('Name of \'Full Name\' field in profile module.'),
494 );
495 }
496 }
497
498 // Import behaviour
499 $form['user']['sync']['import'] = array(
500 '#type' => 'fieldset',
501 '#title' => t('Advanced Sync - Import'),
502 '#collapsible' => TRUE,
503 '#collapsed' => TRUE,
504 );
505
506 $form['user']['sync']['import']['gallery_user_import_groups'] = array(
507 '#type' => 'checkbox',
508 '#title' => t('Import Gallery2 groups'),
509 '#default_value' => variable_get('gallery_user_import_groups', 1),
510 '#description' => t('Import Gallery2 groups into Drupal roles (in addition to users).'),
511 );
512
513 $form['user']['sync']['import']['gallery_user_import_override'] = array(
514 '#type' => 'checkbox',
515 '#title' => t('Override existing Drupal users'),
516 '#default_value' => variable_get('gallery_user_import_override', 0),
517 '#description' => t('Replaces user details (password, email, groups, ...) of existing Drupal users with Gallery2 imported values.'),
518 );
519
520 $form['user']['sync']['import']['gallery_user_import_conflict'] = array(
521 '#type' => 'checkboxes',
522 '#title' => t('Auto-resolve email address conflicts'),
523 '#default_value' => variable_get('gallery_user_import_conflict', array()),
524 '#options' => array(
525 GALLERY_IMPORT_CONFLICT_DUPLICATE => t('Duplicate e-mail addresses'),
526 GALLERY_IMPORT_CONFLICT_INVALID => t('Invalide e-mail addresses')
527 ),
528 '#description' => t('Renames duplicate/invalid e-mail addresses to username@drupaldomain.
529 If this option is disabled you get a list of users to handle conflicts yourself.')
530 );
531
532 // Export behaviour
533 $form['user']['sync']['export'] = array(
534 '#type' => 'fieldset',
535 '#title' => t('Advanced Sync - Export (Synchronize)'),
536 '#collapsible' => TRUE,
537 '#collapsed' => TRUE,
538 );
539
540 $form['user']['sync']['export']['gallery_user_sync_remap'] = array(
541 '#type' => 'checkbox',
542 '#title' => t('Remap all users'),
543 '#default_value' => variable_get('gallery_user_sync_remap', 0),
544 '#description' => t('Remaps all users instead of missing or mismatching ones only.
545 This will completely flush Gallery2\'s \'externalIdMap\'.'),
546 );
547
548 $form['#submit']['_gallery_user_settings_submit'] = array();
549 $form['#submit']['system_settings_form_submit'] = array();
550 return system_settings_form($form);
551 }
552
553 /**
554 * Function _gallery_user_settings_submit().
555 */
556 function _gallery_user_settings_submit($form_id, $form_values) {
557 if ($form_values['op'] == t('Reset to defaults')) {
558 $fullname_changed = variable_get('gallery_use_fullname', 0);
559 }
560 else {
561 $fullname_changed = ($form_values['gallery_use_fullname'] != variable_get('gallery_use_fullname', 0));
562 }
563 if ($fullname_changed) {
564 drupal_set_message(t('Full Name settings have changed. You should now synchronize
565 your users on the <a href="@user-admin">Gallery users</a> page.',
566 array('@user-admin' => url('admin/user/gallery'))));
567 }
568 }