| 1 |
<?php
|
| 2 |
// $Id$
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Provides an API to extend the User Adminstration list by adding filters and data columns.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Implementation of hook_help().
|
| 11 |
*/
|
| 12 |
function userlist_help($section) {
|
| 13 |
switch ($section) {
|
| 14 |
case 'admin/help#userlist':
|
| 15 |
return
|
| 16 |
'<p>' . t('User List provides an API to extend the !user_admin by adding filters and data columns. The module adds one filter and data column through its own API that may help account administration: last access time. Options are provided to hide or reformat several of the default data columns so that the display does not become overly crowded.</p><p>User List displays badge icons to visually indicate commonly needed information for administration: Account blocked, New account, and Account online. These badges may optionally be displayed on user profile pages to user\'s with "administer users" or "view badge icons" access permission.</p><p>User List is packaged with three optional modules to extend its functionality: !User_List_Flag_Account, !User_List_Node_Count and !User_List_TAC_Lite.</p>' .
|
| 17 |
'<h3>API</h3><p>Module developers can extend the User Administration user list by including a userlist callback handler in their module.' .
|
| 18 |
'<pre>function MODULE_userlist() {
|
| 19 |
return array(
|
| 20 |
\'KEY\' => array( //required: key must be unique
|
| 21 |
|
| 22 |
\'table\' => "TABLENAME", //required
|
| 23 |
|
| 24 |
\'field\' => "FIELDNAME", //required
|
| 25 |
|
| 26 |
\'join\' => "FIELD2NAME = 1", //optional: userlist joins tables on uid
|
| 27 |
//additional criteria for the join such
|
| 28 |
//as fid if joining profile_values
|
| 29 |
|
| 30 |
\'aggregate\' => "COUNT", //optional: aggregate function COUNT,
|
| 31 |
//AVG, SUM, MAX, or MIN for field
|
| 32 |
//userlist will group by u.uid and
|
| 33 |
//convert any filter WHERE to HAVING
|
| 34 |
|
| 35 |
\'filter\' => array( //optional: filter is not required, for
|
| 36 |
//example if only adding data column
|
| 37 |
|
| 38 |
\'title\' => \'FILTER_TITLE\', //required
|
| 39 |
|
| 40 |
\'operator\' => ">", //optional: comparison operator
|
| 41 |
//default is greater than ">"
|
| 42 |
|
| 43 |
\'arg\' => \'%d\', //required: typically %d or %s
|
| 44 |
|
| 45 |
\'options\' => array(), //required: key=>value for select
|
| 46 |
|
| 47 |
\'callback\' => \'FUNC_FILTER\', //optional: userlist will callback this
|
| 48 |
//function with selected key, return
|
| 49 |
//array of new key value and operator
|
| 50 |
),
|
| 51 |
|
| 52 |
\'data\' => array( //optional: data is not required, for
|
| 53 |
//example if only adding new filter
|
| 54 |
|
| 55 |
\'title\' => \'COL_TITLE\', //required: name of column
|
| 56 |
|
| 57 |
\'callback\' => \'FUNC_DATA\' //optional: userlist will callback this
|
| 58 |
//function with $row object which includes
|
| 59 |
//u.uid, u.name, u.status, u.created,
|
| 60 |
//u.access, and any other fields from
|
| 61 |
//query, return new value for column
|
| 62 |
//Note that providing a callback will
|
| 63 |
//make data column non-sortable
|
| 64 |
)
|
| 65 |
)
|
| 66 |
);
|
| 67 |
}</pre>' .
|
| 68 |
'<h3>Known Issues</h3><p>User List includes a query builder that helps extend the User Administration user list in most circumstances, but will never be as robust or optimized as a query crafted by hand. For more complex user reporting requirements, another recommended solution would be using Usernode in combination with Views.' . "</p>\n",
|
| 69 |
array(
|
| 70 |
'!user_admin' => l(t('User Adminstration list'), 'admin/user/user'),
|
| 71 |
'!User_List_Flag_Account' => l(t('User List Flag Account'), 'admin/help/userlist_flag_account'),
|
| 72 |
'!User_List_Node_Count' => l(t('User List Node Count'), 'admin/help/userlist_nodecount'),
|
| 73 |
'!User_List_TAC_Lite' => l(t('User List TAC Lite'), 'admin/help/userlist_tac_lite')
|
| 74 |
));
|
| 75 |
|
| 76 |
case 'admin/settings/userlist':
|
| 77 |
return
|
| 78 |
t('User List provides an API to extend the !user_admin by adding filters and data columns. The module adds one filter and data column through its own API that may help account administration: last access time. Options are provided to hide or reformat several of the default data columns so that the display does not become overly crowded. The module also displays badge icons to visually indicate commonly needed information for administration: Account blocked, New account, and Account online.',
|
| 79 |
array(
|
| 80 |
'!user_admin' => l(t('User Adminstration list'), 'admin/user/user')
|
| 81 |
));
|
| 82 |
}
|
| 83 |
}
|
| 84 |
|
| 85 |
/**
|
| 86 |
* Implementation of hook_perm()
|
| 87 |
*/
|
| 88 |
function userlist_perm() {
|
| 89 |
return array('view badge icons');
|
| 90 |
}
|
| 91 |
|
| 92 |
/**
|
| 93 |
* Implementation of hook_menu().
|
| 94 |
*/
|
| 95 |
function userlist_menu($may_cache) {
|
| 96 |
$items = array();
|
| 97 |
if ($may_cache) {
|
| 98 |
$items[] = array(
|
| 99 |
'callback' => 'drupal_get_form',
|
| 100 |
'callback arguments' => array('userlist_settings'),
|
| 101 |
'path' => 'admin/settings/userlist',
|
| 102 |
'title' => 'User List',
|
| 103 |
'description' => t('Provdes hooks to the User List.'),
|
| 104 |
'access' => user_access('administer site configuration')
|
| 105 |
);
|
| 106 |
$items[] = array(
|
| 107 |
'access' => user_access('administer site configuration'),
|
| 108 |
'callback' => 'userlist_settings',
|
| 109 |
'path' => 'admin/settings/userlist/userlist',
|
| 110 |
'title' => t('User List'),
|
| 111 |
'type' => MENU_DEFAULT_LOCAL_TASK,
|
| 112 |
'weight' => -10,
|
| 113 |
);
|
| 114 |
|
| 115 |
$items[] = array(
|
| 116 |
'path' => 'admin/user/user',
|
| 117 |
'title' => t('Users'),
|
| 118 |
'description' => t('List, add, and edit users.'),
|
| 119 |
'callback' => 'userlist_admin',
|
| 120 |
'callback arguments' => array('list'),
|
| 121 |
'access' => user_access('administer users')
|
| 122 |
);
|
| 123 |
$items[] = array(
|
| 124 |
'path' => 'admin/user/user/list',
|
| 125 |
'title' => t('List'),
|
| 126 |
'type' => MENU_DEFAULT_LOCAL_TASK,
|
| 127 |
'weight' => -10
|
| 128 |
);
|
| 129 |
}
|
| 130 |
return $items;
|
| 131 |
}
|
| 132 |
|
| 133 |
/**
|
| 134 |
* Menu callback for settings
|
| 135 |
*
|
| 136 |
* @return
|
| 137 |
* array of form content.
|
| 138 |
*/
|
| 139 |
function userlist_settings() {
|
| 140 |
$form['default'] = array('#type' => 'fieldset', '#title' => t('Default User List Columns'), '#description' => t('Options for default columns in the User Adminstration list.'));
|
| 141 |
$form['default']['userlist_show_status'] = array(
|
| 142 |
'#type' => 'select',
|
| 143 |
'#title' => t('Show the "Status" column?'),
|
| 144 |
'#default_value' => variable_get('userlist_show_status', 1),
|
| 145 |
'#options' => array('1' => t('Yes'), '0' => t('No')),
|
| 146 |
'#description' => t('The Status column displays account as active or blocked. Blocked status can be shown as an icon badge.')
|
| 147 |
);
|
| 148 |
$form['default']['userlist_show_member_for'] = array(
|
| 149 |
'#type' => 'select',
|
| 150 |
'#title' => t('Show the "Member for" column?'),
|
| 151 |
'#default_value' => variable_get('userlist_show_member_for', 1),
|
| 152 |
'#options' => array('1' => t('Yes'), '0' => t('No')),
|
| 153 |
'#description' => t('The Member for column displays how long since the user created their account. New accounts can be shown as an icon badge.')
|
| 154 |
);
|
| 155 |
$form['default']['userlist_show_operations'] = array(
|
| 156 |
'#type' => 'select',
|
| 157 |
'#title' => t('Show the "Operations" column?'),
|
| 158 |
'#default_value' => variable_get('userlist_show_operations', 1),
|
| 159 |
'#options' => array('1' => t('Yes'), '0' => t('No')),
|
| 160 |
'#description' => t('The Operations column displays the Edit link.')
|
| 161 |
);
|
| 162 |
$form['default']['userlist_show_roles'] = array(
|
| 163 |
'#type' => 'select',
|
| 164 |
'#title' => t('Show the "Roles" column list as:'),
|
| 165 |
'#default_value' => variable_get('userlist_show_roles', 1),
|
| 166 |
'#options' => array('1' => t('Bullet list'), '0' => t('Comma list')),
|
| 167 |
'#description' => t('The Roles column displays as a bullet list which can make rows wrap to new lines if a user has many roles.')
|
| 168 |
);
|
| 169 |
|
| 170 |
$form['badge'] = array('#type' => 'fieldset', '#title' => t('User List Badge Icons'));
|
| 171 |
$form['badge']['userlist_badge_profile'] = array(
|
| 172 |
'#type' => 'select',
|
| 173 |
'#title' => t('Show badge icons on user profile page?'),
|
| 174 |
'#default_value' => variable_get('userlist_badge_profile', 1),
|
| 175 |
'#options' => array('1' => t('Yes'), '0' => t('No'))
|
| 176 |
);
|
| 177 |
$form['badge']['userlist_badge_new'] = array(
|
| 178 |
'#type' => 'textfield',
|
| 179 |
'#size' => 4,
|
| 180 |
'#title' => t('Days since account creation to show New account badge'),
|
| 181 |
'#default_value' => (int)variable_get('userlist_badge_new', 30),
|
| 182 |
'#description' => t('Set to 0 to disable.')
|
| 183 |
);
|
| 184 |
$form['badge']['userlist_badge_online'] = array(
|
| 185 |
'#type' => 'textfield',
|
| 186 |
'#size' => 4,
|
| 187 |
'#title' => t('Minutes since last account access to show Account online badge'),
|
| 188 |
'#default_value' => (int)variable_get('userlist_badge_online', 15),
|
| 189 |
'#description' => t('Set to 0 to disable.')
|
| 190 |
);
|
| 191 |
|
| 192 |
$form['userlist_debug_sql'] = array(
|
| 193 |
'#type' => 'select',
|
| 194 |
'#title' => t('Show query builder debug in status message?'),
|
| 195 |
'#default_value' => variable_get('userlist_debug_sql', 0),
|
| 196 |
'#options' => array('1' => t('Yes'), '0' => t('No'))
|
| 197 |
);
|
| 198 |
return system_settings_form($form);
|
| 199 |
}
|
| 200 |
|
| 201 |
function userlist_admin($callback_arg = '') {
|
| 202 |
$op = isset($_POST['op']) ? $_POST['op'] : $callback_arg;
|
| 203 |
|
| 204 |
switch ($op) {
|
| 205 |
case 'search':
|
| 206 |
case t('Search'):
|
| 207 |
$output = drupal_get_form('search_form', url('admin/user/search'), $_POST['keys'], 'user') . search_data($_POST['keys'], 'user');
|
| 208 |
break;
|
| 209 |
case t('Create new account'):
|
| 210 |
case 'create':
|
| 211 |
$output = drupal_get_form('user_register');
|
| 212 |
break;
|
| 213 |
default:
|
| 214 |
if ($_POST['accounts'] && $_POST['operation'] == 'delete') {
|
| 215 |
$output = drupal_get_form('user_multiple_delete_confirm');
|
| 216 |
}
|
| 217 |
else {
|
| 218 |
$output = drupal_get_form('user_filter_form');
|
| 219 |
$output .= drupal_get_form('userlist_user_admin_account');
|
| 220 |
}
|
| 221 |
}
|
| 222 |
return $output;
|
| 223 |
}
|
| 224 |
|
| 225 |
/**
|
| 226 |
* Implementation of hook_user().
|
| 227 |
*/
|
| 228 |
function userlist_user($op, &$edit, &$account, $category = NULL) {
|
| 229 |
switch ($op) {
|
| 230 |
case 'load':
|
| 231 |
$account->userlist_badges = userlist_get_badges($account);
|
| 232 |
break;
|
| 233 |
|
| 234 |
case 'view':
|
| 235 |
if (arg(0) != 'user' || arg(2)) return;
|
| 236 |
if (!variable_get('userlist_badge_profile', 1)) return;
|
| 237 |
if (!user_access('administer users') && !user_access('view badge icons')) return;
|
| 238 |
|
| 239 |
drupal_add_js(drupal_get_path('module', 'userlist') . '/userlist.js');
|
| 240 |
drupal_add_js(array(
|
| 241 |
'userlist' => array(
|
| 242 |
'badges' => $account->userlist_badges
|
| 243 |
),
|
| 244 |
), 'setting');
|
| 245 |
|
| 246 |
break;
|
| 247 |
}
|
| 248 |
}
|
| 249 |
|
| 250 |
function userlist_form_alter($form_id, &$form) {
|
| 251 |
switch ($form_id) {
|
| 252 |
case 'user_filter_form':
|
| 253 |
userlist_user_filter_form($form_id, $form);
|
| 254 |
break;
|
| 255 |
}
|
| 256 |
}
|
| 257 |
|
| 258 |
function userlist_user_filter_form($form_id, &$form) {
|
| 259 |
global $userlist_callbacks;
|
| 260 |
if (!isset($userlist_callbacks)) {
|
| 261 |
$userlist_callbacks = module_invoke_all('userlist');
|
| 262 |
}
|
| 263 |
|
| 264 |
$session = &$_SESSION['user_overview_filter'];
|
| 265 |
$session = is_array($session) ? $session : array();
|
| 266 |
$filters = user_filters();
|
| 267 |
|
| 268 |
//begin userlist hook
|
| 269 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 270 |
if (isset($value['filter'])) {
|
| 271 |
$filters[$callback] = $value['filter'] + array('table' => $value['table'], 'field' => $value['field']);
|
| 272 |
}
|
| 273 |
}
|
| 274 |
//end userlist hook
|
| 275 |
|
| 276 |
$i = 0;
|
| 277 |
$form['filters'] = array(
|
| 278 |
'#type' => 'fieldset',
|
| 279 |
'#title' => t('Show only users where'),
|
| 280 |
'#theme' => 'user_filters',
|
| 281 |
);
|
| 282 |
foreach ($session as $filter) {
|
| 283 |
list($type, $value) = $filter;
|
| 284 |
$string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
|
| 285 |
// Merge an array of arrays into one if necessary.
|
| 286 |
$options = $type == 'permission' ? call_user_func_array('array_merge', $filters[$type]['options']) : $filters[$type]['options'];
|
| 287 |
$form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $options[$value])));
|
| 288 |
$filter_active[] = $type;
|
| 289 |
}
|
| 290 |
|
| 291 |
foreach ($filters as $key => $filter) {
|
| 292 |
// Show filters that are not currently active (in $_SESSION)
|
| 293 |
if (!in_array($key, (array)$filter_active)) {
|
| 294 |
$names[$key] = $filter['title'];
|
| 295 |
$form['filters']['status'][$key] = array(
|
| 296 |
'#type' => 'select',
|
| 297 |
'#options' => $filter['options'],
|
| 298 |
);
|
| 299 |
}
|
| 300 |
}
|
| 301 |
$form['filters']['filter'] = array(
|
| 302 |
'#type' => 'radios',
|
| 303 |
'#options' => $names,
|
| 304 |
);
|
| 305 |
$form['filters']['buttons']['submit'] = array(
|
| 306 |
'#type' => 'submit',
|
| 307 |
'#value' => (count($session) ? t('Refine') : t('Filter'))
|
| 308 |
);
|
| 309 |
if (count($session)) {
|
| 310 |
$form['filters']['buttons']['undo'] = array(
|
| 311 |
'#type' => 'submit',
|
| 312 |
'#value' => t('Undo')
|
| 313 |
);
|
| 314 |
$form['filters']['buttons']['reset'] = array(
|
| 315 |
'#type' => 'submit',
|
| 316 |
'#value' => t('Reset')
|
| 317 |
);
|
| 318 |
}
|
| 319 |
|
| 320 |
unset($form['#submit']);
|
| 321 |
$form['#submit']['userlist_user_filter_form_submit'] = array($form);
|
| 322 |
}
|
| 323 |
|
| 324 |
function userlist_user_filter_form_submit($form_id, $form_values, $form) {
|
| 325 |
global $userlist_callbacks;
|
| 326 |
if (!isset($userlist_callbacks)) {
|
| 327 |
$userlist_callbacks = module_invoke_all('userlist');
|
| 328 |
}
|
| 329 |
|
| 330 |
$op = $form_values['op'];
|
| 331 |
$filters = user_filters();
|
| 332 |
|
| 333 |
//begin userlist hook
|
| 334 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 335 |
if (isset($value['filter'])) {
|
| 336 |
$filters[$callback] = $value['filter'] + array('table' => $value['table'], 'field' => $value['field'], 'join' => $value['join'], 'aggregate' => $value['aggregate']);
|
| 337 |
}
|
| 338 |
}
|
| 339 |
//end userlist hook
|
| 340 |
|
| 341 |
switch ($op) {
|
| 342 |
case t('Filter'): case t('Refine'):
|
| 343 |
if (isset($form_values['filter'])) {
|
| 344 |
$filter = $form_values['filter'];
|
| 345 |
// Merge an array of arrays into one if necessary.
|
| 346 |
$options = $filter == 'permission' ? call_user_func_array('array_merge', $filters[$filter]['options']) : $filters[$filter]['options'];
|
| 347 |
if (isset($options[$form_values[$filter]])) {
|
| 348 |
$_SESSION['user_overview_filter'][] = array($filter, $form_values[$filter]);
|
| 349 |
}
|
| 350 |
}
|
| 351 |
break;
|
| 352 |
case t('Undo'):
|
| 353 |
array_pop($_SESSION['user_overview_filter']);
|
| 354 |
break;
|
| 355 |
case t('Reset'):
|
| 356 |
$_SESSION['user_overview_filter'] = array();
|
| 357 |
break;
|
| 358 |
case t('Update'):
|
| 359 |
return;
|
| 360 |
}
|
| 361 |
|
| 362 |
return 'admin/user/user';
|
| 363 |
}
|
| 364 |
|
| 365 |
function userlist_user_admin_account() {
|
| 366 |
global $userlist_callbacks;
|
| 367 |
if (!isset($userlist_callbacks)) {
|
| 368 |
$userlist_callbacks = module_invoke_all('userlist');
|
| 369 |
}
|
| 370 |
|
| 371 |
$filter = userlist_build_query();
|
| 372 |
$userlist_show_status = variable_get('userlist_show_status', 1);
|
| 373 |
$userlist_show_member_for = variable_get('userlist_show_member_for', 1);
|
| 374 |
$userlist_show_operations = variable_get('userlist_show_operations', 1);
|
| 375 |
|
| 376 |
$badge_setting['userlist_badge_new'] = variable_get('userlist_badge_new', 30);
|
| 377 |
$badge_setting['userlist_badge_online'] = variable_get('userlist_badge_online', 15);
|
| 378 |
|
| 379 |
$badge_setting['add_css'] = true;
|
| 380 |
drupal_add_css(drupal_get_path('module', 'userlist') .'/userlist.css');
|
| 381 |
|
| 382 |
if (module_exists('userlist_flag_account')) {
|
| 383 |
drupal_add_css(drupal_get_path('module', 'userlist_flag_account') .'/userlist_flag_account.css');
|
| 384 |
$badge_setting['userlist_flag_account_flags'] = userlist_flag_account_get_flags();
|
| 385 |
}
|
| 386 |
|
| 387 |
$header = array(
|
| 388 |
array(), //checkbox
|
| 389 |
array(), //badge icons
|
| 390 |
array('data' => t('Username'), 'field' => 'u.name')
|
| 391 |
);
|
| 392 |
if ($userlist_show_status) {
|
| 393 |
array_push($header,
|
| 394 |
array('data' => t('Status'), 'field' => 'u.status')
|
| 395 |
);
|
| 396 |
}
|
| 397 |
array_push($header, t('Roles'));
|
| 398 |
|
| 399 |
//begin userlist hook
|
| 400 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 401 |
if (isset($value['data'])) {
|
| 402 |
if ($value['table'] && $value['field'] && !isset($value['data']['callback'])) {
|
| 403 |
if ($value['aggregate'] = userlist_get_aggregate_function($value['aggregate'])) {
|
| 404 |
$header[] = array('data' => $value['data']['title'], 'field' => $value['field'] . '_' . $value['aggregate']);
|
| 405 |
}
|
| 406 |
else {
|
| 407 |
$header[] = array('data' => $value['data']['title'], 'field' => userlist_get_table_name($value['table']) . '.' . $value['field']);
|
| 408 |
}
|
| 409 |
}
|
| 410 |
else {
|
| 411 |
$header[] = $value['data']['title'];
|
| 412 |
}
|
| 413 |
}
|
| 414 |
}
|
| 415 |
//end userlist hook
|
| 416 |
if ($userlist_show_member_for) {
|
| 417 |
array_push($header,
|
| 418 |
array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
|
| 419 |
array('data' => t('Last access'), 'field' => 'u.access')
|
| 420 |
);
|
| 421 |
}
|
| 422 |
else {
|
| 423 |
array_push($header,
|
| 424 |
array('data' => t('Last access'), 'field' => 'u.access', 'sort' => 'desc')
|
| 425 |
);
|
| 426 |
}
|
| 427 |
if ($userlist_show_operations) {
|
| 428 |
array_push($header,
|
| 429 |
t('Operations')
|
| 430 |
);
|
| 431 |
}
|
| 432 |
|
| 433 |
$sql = 'SELECT DISTINCT ' . $filter['fields'] . ' FROM {users} u LEFT JOIN {users_roles} ur ON (u.uid = ur.uid) ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'] . $filter['group_by'] . $filter['having'];
|
| 434 |
$sql .= tablesort_sql($header);
|
| 435 |
if (isset($filter['having_count'])) {
|
| 436 |
$query_count = 'SELECT COUNT(*) FROM (SELECT COUNT(DISTINCT u.uid) FROM {users} u LEFT JOIN {users_roles} ur ON (u.uid = ur.uid) ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'] . $filter['group_by'] . $filter['having_count'] . ') AS subquery';
|
| 437 |
}
|
| 438 |
else {
|
| 439 |
$query_count = 'SELECT COUNT(DISTINCT u.uid) FROM {users} u LEFT JOIN {users_roles} ur ON (u.uid = ur.uid) ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'];
|
| 440 |
}
|
| 441 |
|
| 442 |
$result = pager_query($sql, 50, 0, $query_count, $filter['args']);
|
| 443 |
//***DEBUG***
|
| 444 |
if (variable_get('userlist_debug_sql', 0)) {
|
| 445 |
drupal_set_message("<strong>userlist sql=</strong>" . $sql . " (<strong>args=</strong>". implode("|", $filter['args']) . ")", 'warning');
|
| 446 |
drupal_set_message("<strong>userlist sql pager=</strong>" . $query_count . " (<strong>args=</strong>". implode("|", $filter['args']) . ")", 'warning');
|
| 447 |
}
|
| 448 |
|
| 449 |
$form['options'] = array(
|
| 450 |
'#type' => 'fieldset',
|
| 451 |
'#title' => t('Update options'),
|
| 452 |
'#prefix' => '<div class="container-inline">',
|
| 453 |
'#suffix' => '</div>',
|
| 454 |
);
|
| 455 |
$options = array();
|
| 456 |
foreach (module_invoke_all('user_operations') as $operation => $array) {
|
| 457 |
$options[$operation] = $array['label'];
|
| 458 |
}
|
| 459 |
$form['options']['operation'] = array(
|
| 460 |
'#type' => 'select',
|
| 461 |
'#options' => $options,
|
| 462 |
'#default_value' => 'unblock',
|
| 463 |
);
|
| 464 |
$form['options']['submit'] = array(
|
| 465 |
'#type' => 'submit',
|
| 466 |
'#value' => t('Update'),
|
| 467 |
);
|
| 468 |
|
| 469 |
$form['#theme'] = 'userlist_user_admin_account';
|
| 470 |
|
| 471 |
$destination = drupal_get_destination();
|
| 472 |
|
| 473 |
$status = array(t('blocked'), t('active'));
|
| 474 |
$roles = user_roles(1);
|
| 475 |
|
| 476 |
while ($account = db_fetch_object($result)) {
|
| 477 |
$accounts[$account->uid] = '';
|
| 478 |
$form['badges'][$account->uid] = array('#value' => userlist_get_badges($account, $badge_setting));
|
| 479 |
$form['name'][$account->uid] = array('#value' => theme('username', $account));
|
| 480 |
if ($userlist_show_status) {
|
| 481 |
$form['status'][$account->uid] = array('#value' => $status[$account->status]);
|
| 482 |
}
|
| 483 |
|
| 484 |
$users_roles = array();
|
| 485 |
$roles_result = db_query('SELECT rid FROM {users_roles} WHERE uid = %d', $account->uid);
|
| 486 |
while ($user_role = db_fetch_object($roles_result)) {
|
| 487 |
$users_roles[] = $roles[$user_role->rid];
|
| 488 |
}
|
| 489 |
asort($users_roles);
|
| 490 |
|
| 491 |
if (variable_get('userlist_show_roles', 1)) {
|
| 492 |
$form['roles'][$account->uid][0] = array('#value' => theme('item_list', $users_roles));
|
| 493 |
}
|
| 494 |
else {
|
| 495 |
$form['roles'][$account->uid][0] = array('#value' => implode(', ', $users_roles));
|
| 496 |
}
|
| 497 |
|
| 498 |
//begin userlist hook
|
| 499 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 500 |
if (isset($value['data'])) {
|
| 501 |
if (function_exists($value['data']['callback'])) {
|
| 502 |
$form[$callback][$account->uid] = array('#value' => call_user_func($value['data']['callback'], $account)); //pass row object - not full account
|
| 503 |
}
|
| 504 |
else if ($value['field']) {
|
| 505 |
if ($value['aggregate'] = userlist_get_aggregate_function($value['aggregate'])) {
|
| 506 |
$value['field'] = $value['field'] . '_' . $value['aggregate'];
|
| 507 |
}
|
| 508 |
$form[$callback][$account->uid] = array('#value' => $account->$value['field']);
|
| 509 |
}
|
| 510 |
}
|
| 511 |
}
|
| 512 |
//end userlist hook
|
| 513 |
|
| 514 |
if ($userlist_show_member_for) {
|
| 515 |
$form['member_for'][$account->uid] = array('#value' => format_interval(time() - $account->created));
|
| 516 |
}
|
| 517 |
$form['last_access'][$account->uid] = array('#value' => $account->access ? format_interval(time() - $account->access) : t('never'));
|
| 518 |
if ($userlist_show_operations) {
|
| 519 |
$form['operations'][$account->uid] = array('#value' => l(t('edit'), "user/$account->uid/edit", array(), $destination));
|
| 520 |
}
|
| 521 |
}
|
| 522 |
$form['accounts'] = array(
|
| 523 |
'#type' => 'checkboxes',
|
| 524 |
'#options' => $accounts
|
| 525 |
);
|
| 526 |
$form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
|
| 527 |
return $form;
|
| 528 |
}
|
| 529 |
|
| 530 |
function theme_userlist_user_admin_account($form) {
|
| 531 |
global $userlist_callbacks;
|
| 532 |
if (!isset($userlist_callbacks)) {
|
| 533 |
$userlist_callbacks = module_invoke_all('userlist');
|
| 534 |
}
|
| 535 |
|
| 536 |
// Overview table:
|
| 537 |
$userlist_show_status = variable_get('userlist_show_status', 1);
|
| 538 |
$userlist_show_member_for = variable_get('userlist_show_member_for', 1);
|
| 539 |
$userlist_show_operations = variable_get('userlist_show_operations', 1);
|
| 540 |
|
| 541 |
$header = array(
|
| 542 |
theme('table_select_header_cell'),
|
| 543 |
array('data' => ' ', 'class' => 'userlist-badges'), //badge icons
|
| 544 |
array('data' => t('Username'), 'class' => 'userlist-nowrap', 'field' => 'u.name')
|
| 545 |
);
|
| 546 |
if ($userlist_show_status) {
|
| 547 |
array_push($header,
|
| 548 |
array('data' => t('Status'), 'class' => 'userlist-nowrap', 'field' => 'u.status')
|
| 549 |
);
|
| 550 |
}
|
| 551 |
array_push($header, t('Roles'));
|
| 552 |
|
| 553 |
//begin userlist hook
|
| 554 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 555 |
if (isset($value['data'])) {
|
| 556 |
if ($value['table'] && $value['field'] && !isset($value['data']['callback'])) {
|
| 557 |
$header[] = array('data' => $value['data']['title'], 'class' => 'userlist-nowrap', 'field' => userlist_get_table_name($value['table']) . '.' . $value['field']);
|
| 558 |
}
|
| 559 |
else {
|
| 560 |
$header[] = array('data' => $value['data']['title'], 'class' => 'userlist-nowrap');
|
| 561 |
}
|
| 562 |
$colspan++;
|
| 563 |
}
|
| 564 |
}
|
| 565 |
//end userlist hook
|
| 566 |
|
| 567 |
if ($userlist_show_member_for) {
|
| 568 |
array_push($header,
|
| 569 |
array('data' => t('Member for'), 'class' => 'userlist-nowrap', 'field' => 'u.created', 'sort' => 'desc'),
|
| 570 |
array('data' => t('Last access'), 'class' => 'userlist-nowrap', 'field' => 'u.access')
|
| 571 |
);
|
| 572 |
}
|
| 573 |
else {
|
| 574 |
array_push($header,
|
| 575 |
array('data' => t('Last access'), 'class' => 'userlist-nowrap', 'field' => 'u.access', 'sort' => 'desc')
|
| 576 |
);
|
| 577 |
}
|
| 578 |
if ($userlist_show_operations) {
|
| 579 |
array_push($header,
|
| 580 |
t('Operations')
|
| 581 |
);
|
| 582 |
}
|
| 583 |
|
| 584 |
$output = drupal_render($form['options']);
|
| 585 |
if (isset($form['name']) && is_array($form['name'])) {
|
| 586 |
foreach (element_children($form['name']) as $key) {
|
| 587 |
$rows[$i] = array(
|
| 588 |
drupal_render($form['accounts'][$key]),
|
| 589 |
array(
|
| 590 |
'data' => drupal_render($form['badges'][$key]),
|
| 591 |
'class' => 'userlist-nowrap'
|
| 592 |
),
|
| 593 |
drupal_render($form['name'][$key])
|
| 594 |
);
|
| 595 |
if ($userlist_show_status) {
|
| 596 |
array_push($rows[$i],
|
| 597 |
drupal_render($form['status'][$key])
|
| 598 |
);
|
| 599 |
}
|
| 600 |
array_push($rows[$i],
|
| 601 |
drupal_render($form['roles'][$key])
|
| 602 |
);
|
| 603 |
|
| 604 |
//begin userlist hook
|
| 605 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 606 |
if (isset($value['data'])) {
|
| 607 |
array_push($rows[$i], drupal_render($form[$callback][$key]));
|
| 608 |
}
|
| 609 |
}
|
| 610 |
//end userlist hook
|
| 611 |
if ($userlist_show_member_for) {
|
| 612 |
array_push($rows[$i],
|
| 613 |
array(
|
| 614 |
'data' => drupal_render($form['member_for'][$key]),
|
| 615 |
'class' => 'userlist-nowrap'
|
| 616 |
)
|
| 617 |
);
|
| 618 |
}
|
| 619 |
array_push($rows[$i],
|
| 620 |
array(
|
| 621 |
'data' => drupal_render($form['last_access'][$key]),
|
| 622 |
'class' => 'userlist-nowrap'
|
| 623 |
)
|
| 624 |
);
|
| 625 |
if ($userlist_show_operations) {
|
| 626 |
array_push($rows[$i],
|
| 627 |
drupal_render($form['operations'][$key])
|
| 628 |
);
|
| 629 |
}
|
| 630 |
|
| 631 |
$i++;
|
| 632 |
}
|
| 633 |
}
|
| 634 |
else {
|
| 635 |
if ($userlist_show_status) {
|
| 636 |
$optional_columns++;
|
| 637 |
}
|
| 638 |
if ($userlist_show_member_for) {
|
| 639 |
$optional_columns++;
|
| 640 |
}
|
| 641 |
if ($userlist_show_member_for) {
|
| 642 |
$optional_columns++;
|
| 643 |
}
|
| 644 |
if ($userlist_show_operations) {
|
| 645 |
$optional_columns++;
|
| 646 |
}
|
| 647 |
$rows[] = array(array('data' => t('No users available.'), 'colspan' => 5 + $optional_columns + $colspan));
|
| 648 |
}
|
| 649 |
|
| 650 |
$output .= theme('table', $header, $rows);
|
| 651 |
if ($form['pager']['#value']) {
|
| 652 |
$output .= drupal_render($form['pager']);
|
| 653 |
}
|
| 654 |
|
| 655 |
$output .= drupal_render($form);
|
| 656 |
|
| 657 |
return $output;
|
| 658 |
}
|
| 659 |
|
| 660 |
/**
|
| 661 |
* Submit the user administration update form.
|
| 662 |
*/
|
| 663 |
function userlist_user_admin_account_submit($form_id, $form_values) {
|
| 664 |
//pass to user module
|
| 665 |
user_admin_account_submit($form_id, $form_values);
|
| 666 |
}
|
| 667 |
|
| 668 |
/**
|
| 669 |
* Build query.
|
| 670 |
*/
|
| 671 |
function userlist_build_query() {
|
| 672 |
global $userlist_callbacks;
|
| 673 |
if (!isset($userlist_callbacks)) {
|
| 674 |
$userlist_callbacks = module_invoke_all('userlist');
|
| 675 |
}
|
| 676 |
|
| 677 |
$filters = user_filters();
|
| 678 |
$where = $args = $join = array();
|
| 679 |
$fields = array('u.uid', 'u.name', 'u.status', 'u.created', 'u.access');
|
| 680 |
|
| 681 |
//begin userlist hook
|
| 682 |
foreach ($userlist_callbacks as $callback => $value) {
|
| 683 |
if (isset($value['filter'])) {
|
| 684 |
$filters[$callback] = $value['filter'] + array('table' => $value['table'], 'field' => $value['field'], 'join' => $value['join'], 'aggregate' => $value['aggregate']);
|
| 685 |
}
|
| 686 |
|
| 687 |
//==table
|
| 688 |
if ($table = userlist_get_table_name($value['table'])) {
|
| 689 |
if (!in_array($table, array('u', 'ur'))) { //join if not users or users_roles
|
| 690 |
$join[] = $value['join'] ?
|
| 691 |
'LEFT JOIN {' . $table . '} ' . $table . ' ON (u.uid = ' . $table . '.uid' . ' AND ' . $table . '.' . $value['join'] . ')' :
|
| 692 |
'LEFT JOIN {' . $table . '} ' . $table . ' ON (u.uid = ' . $table . '.uid' . ')';
|
| 693 |
}
|
| 694 |
}
|
| 695 |
|
| 696 |
//==fields
|
| 697 |
if ($table && $value['field']) {
|
| 698 |
if ($value['aggregate'] = userlist_get_aggregate_function($value['aggregate'])) {
|
| 699 |
$fields[] = strtoupper($value['aggregate']) . '(DISTINCT ' . $table . '.' . $value['field'] . ') AS ' . $value['field'] . '_' . $value['aggregate'];
|
| 700 |
$group_by = ' GROUP BY u.uid';
|
| 701 |
}
|
| 702 |
else {
|
| 703 |
$fields[] = $table . '.' . $value['field'];
|
| 704 |
}
|
| 705 |
}
|
| 706 |
}
|
| 707 |
//end userlist hook
|
| 708 |
|
| 709 |
// Build query
|
| 710 |
foreach ($_SESSION['user_overview_filter'] as $filter) {
|
| 711 |
list($key, $value) = $filter;
|
| 712 |
// This checks to see if this permission filter is an enabled permission for the authenticated role.
|
| 713 |
// If so, then all users would be listed, and we can skip adding it to the filter query.
|
| 714 |
if ($key == 'permission') {
|
| 715 |
$account = new stdClass();
|
| 716 |
$account->uid = 'user_filter';
|
| 717 |
$account->roles = array(DRUPAL_AUTHENTICATED_RID => 1);
|
| 718 |
if (user_access($value, $account)) {
|
| 719 |
continue;
|
| 720 |
}
|
| 721 |
}
|
| 722 |
|
| 723 |
//begin userlist hook
|
| 724 |
//==args
|
| 725 |
if ($filters[$key]['callback'] && function_exists($filters[$key]['callback'])) {
|
| 726 |
list($args[],$operator) = call_user_func($filters[$key]['callback'], $value);
|
| 727 |
}
|
| 728 |
else {
|
| 729 |
$args[] = $value;
|
| 730 |
}
|
| 731 |
|
| 732 |
//==where
|
| 733 |
if ($filters[$key]['table'] && $filters[$key]['field'] && $filters[$key]['arg']) {
|
| 734 |
$table = userlist_get_table_name($filters[$key]['table']);
|
| 735 |
$field = $filters[$key]['field'];
|
| 736 |
if (!$operator) {
|
| 737 |
$operator = $filters[$key]['operator'] ? $filters[$key]['operator'] : ">";
|
| 738 |
}
|
| 739 |
if ($filters[$key]['aggregate'] = userlist_get_aggregate_function($filters[$key]['aggregate'])) {
|
| 740 |
// format: field_count > %d
|
| 741 |
$having[] = $field . '_' . $filters[$key]['aggregate'] . " " . $operator . " " . $filters[$key]['arg'];
|
| 742 |
// format: COUNT(DISTINCT table.field) > %d
|
| 743 |
$having_count[] = strtoupper($filters[$key]['aggregate']) . '(DISTINCT ' . $table . '.' . $field . ') ' . $operator . " " . $filters[$key]['arg'];
|
| 744 |
//pop from args
|
| 745 |
$args_having[] = array_pop($args);
|
| 746 |
}
|
| 747 |
else {
|
| 748 |
// format: table.field > %d
|
| 749 |
$where[] = $table . '.' . $field . " " . $operator . " " . $filters[$key]['arg'];
|
| 750 |
}
|
| 751 |
|
| 752 |
}
|
| 753 |
elseif ($filters[$key]['where']) {
|
| 754 |
$where[] = $filters[$key]['where'];
|
| 755 |
}
|
| 756 |
//end userlist hook
|
| 757 |
|
| 758 |
unset($operator);
|
| 759 |
}
|
| 760 |
|
| 761 |
$fields = implode(', ', array_unique($fields));
|
| 762 |
$join = count($join) ? ' ' .implode(' ', array_unique($join)) : '';
|
| 763 |
|
| 764 |
$where = count($where) ? 'AND ' .implode(' AND ', $where) : '';
|
| 765 |
$args = array_merge($args, (array)$args_having);
|
| 766 |
|
| 767 |
if (count($having)) $having = ' HAVING ' . implode(' AND ', $having);
|
| 768 |
if (count($having_count)) $having_count = ' HAVING ' . implode(' AND ', $having_count);
|
| 769 |
|
| 770 |
return array(
|
| 771 |
'fields' => $fields,
|
| 772 |
'join' => $join,
|
| 773 |
'where' => $where,
|
| 774 |
'args' => $args,
|
| 775 |
'having' => $having,
|
| 776 |
'having_count' => $having_count,
|
| 777 |
'group_by' => $group_by,
|
| 778 |
);
|
| 779 |
}
|
| 780 |
|
| 781 |
/**
|
| 782 |
* Build query helper.
|
| 783 |
*/
|
| 784 |
function userlist_get_table_name($table) {
|
| 785 |
if ($table == 'users') return 'u';
|
| 786 |
if ($table == 'users_roles') return 'ur';
|
| 787 |
return db_escape_table($table);
|
| 788 |
}
|
| 789 |
|
| 790 |
/**
|
| 791 |
* Build query helper.
|
| 792 |
*/
|
| 793 |
function userlist_get_aggregate_function($function) {
|
| 794 |
$function = strtolower($function);
|
| 795 |
if (in_array($function, array('count', 'avg', 'sum', 'max', 'min'))) {
|
| 796 |
return $function;
|
| 797 |
}
|
| 798 |
return FALSE;
|
| 799 |
}
|
| 800 |
|
| 801 |
/**
|
| 802 |
* Internal function.
|
| 803 |
*/
|
| 804 |
function userlist_get_badges($account, $param = array()) {
|
| 805 |
// $param can be passed so that we don't have to rebuild for every account on user list
|
| 806 |
if (!isset($param['userlist_badge_new'])) $param['userlist_badge_new'] = variable_get('userlist_badge_new', 30);
|
| 807 |
if (!isset($param['userlist_badge_online'])) $param['userlist_badge_online'] = variable_get('userlist_badge_online', 15);
|
| 808 |
|
| 809 |
$time = time();
|
| 810 |
$new_time = $time - 3600*24*$param['userlist_badge_new']; //30 days
|
| 811 |
$online_time = $time - 60*$param['userlist_badge_online']; //15 minutes
|
| 812 |
$badges = '';
|
| 813 |
|
| 814 |
if (!$param['add_css']) drupal_add_css(drupal_get_path('module', 'userlist') . '/userlist.css');
|
| 815 |
|
| 816 |
if ($param['userlist_badge_online'] && $account->access && $account->access > $online_time) {
|
| 817 |
$badges .= '<span class="userlist-badge userlist-account-online" title="' . t('Account online') . '">online</span>';
|
| 818 |
}
|
| 819 |
if ($param['userlist_badge_new'] && $account->created > $new_time) {
|
| 820 |
$badges .= '<span class="userlist-badge userlist-account-new" title="' . t('New account') . '">new</span>';
|
| 821 |
}
|
| 822 |
if ($account->status == 0) {
|
| 823 |
$badges .= '<span class="userlist-badge userlist-account-blocked" title="' . t('Account blocked') . '">blocked</span>';
|
| 824 |
}
|
| 825 |
|
| 826 |
if (module_exists('userlist_flag_account')) {
|
| 827 |
if (!isset($param['userlist_flag_account_flags'])) $param['userlist_flag_account_flags'] = userlist_flag_account_get_flags();
|
| 828 |
if (!$param['add_css']) drupal_add_css(drupal_get_path('module', 'userlist_flag_account') . '/userlist_flag_account.css');
|
| 829 |
$badges .= userlist_flag_account_get_badges($param['userlist_flag_account_flags'], $account->uid);
|
| 830 |
}
|
| 831 |
|
| 832 |
return $badges;
|
| 833 |
}
|
| 834 |
|
| 835 |
/**
|
| 836 |
* Callback handler for userlist
|
| 837 |
*/
|
| 838 |
function userlist_userlist() {
|
| 839 |
return array(
|
| 840 |
'last_access' => array(
|
| 841 |
'table' => "users",
|
| 842 |
'field' => "access",
|
| 843 |
'filter' => array(
|
| 844 |
'title' => t('last access'),
|
| 845 |
'operator' => ">",
|
| 846 |
'arg' => '%d',
|
| 847 |
'options' => array(0 => 'never') + drupal_map_assoc(array(300, 900, 3600, 86400, 604800, 2419200, 7257600, 31536000), 'format_interval'),
|
| 848 |
'callback' => 'userlist_last_access_filter',
|
| 849 |
)
|
| 850 |
)
|
| 851 |
);
|
| 852 |
}
|
| 853 |
|
| 854 |
function userlist_last_access_filter($value) {
|
| 855 |
if ($value == 0) {
|
| 856 |
return array(0, "=");
|
| 857 |
}
|
| 858 |
return array(time() - $value);
|
| 859 |
}
|