/[drupal]/contributions/modules/accounttypes/accounttypes.module
ViewVC logotype

Contents of /contributions/modules/accounttypes/accounttypes.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Wed Nov 28 22:36:12 2007 UTC (2 years ago) by rconstantine
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +0 -0 lines
File MIME type: text/x-php
#189589 by jacob.everist - said postgres install wasn't working. now it should. also added some notes for phpdoc
1 <?php
2 /**
3 * This is the accounttypes module
4 *
5 * <p>This file contains information on the accounttypes module. The module allows
6 * a site admin to create account types which can be assigned roles and which will
7 * make the administration of large role-sets easier.</p>
8 *
9 * @version $Id$;
10 * @package AccountTypes
11 * @category NeighborForge
12 * @author Ryan Constantine
13 * @filesource
14 * @license http://www.gnu.org/licenses/gpl.txt GNU_GENERAL_PUBLIC_LICENSE
15 * @link none yet
16 */
17 define('STD_ACCOUNT_TYPE', '1');
18
19 /**
20 * Implementation of hook_help
21 *
22 * Display help and module information
23 * @param string section which section of the site we're displaying help
24 * @return help text for section
25 */
26 function accounttypes_help($section='') {
27
28 $output = '';
29
30 switch ($section) {
31 case "admin/help#accounttypes":
32 $output = '<p>' . t("Allows the restriction of available roles based on admin-defined account types. For small sites with few roles, there is little chance of accidentally assigning the wrong role to a user. For larger sites with many defined roles, such a thing could happen, especially if assignment of roles has been delegated."). '</p>';
33 break;
34 }
35
36 return $output;
37 } // function accounttypes_help()
38
39 /**
40 * Implementation of hook_perm
41 *
42 * Valid permissions for this module
43 * @return array An array of valid permissions for the accounttypes module
44 */
45 function accounttypes_perm() {
46
47 return array('administer accounttypes', 'view accounttypes', 'assign accounttypes');
48 } // function accounttypes_perm()
49
50 /**
51 * Implementation of hook_menu
52 *
53 * The menu item(s) for this module.
54 * @return array An array of arrays, to add menu entries to the system menu.
55 */
56 function accounttypes_menu($may_cache) {
57 $items = array();
58 if ($may_cache) {
59 $items[] = array( //view, add, delete, edit account types (names), admin roles, etc from this main page's tabs
60 'path' => 'admin/user/accounttypes',
61 'title' => t('Account Types'),
62 'callback' => 'drupal_get_form',
63 'callback arguments' => array('accounttypes_new_edit'),
64 'access' => user_access('administer accounttypes'),
65 'description' => t('Create and maintain Account Types to more easily manage large numbers of roles and users.'),
66 'type' => MENU_NORMAL_ITEM,
67 );
68
69 $items[] = array(
70 'path' => 'admin/user/accounttypes/overview',
71 'title' => t('Overview'),
72 'access' => user_access('administer accounttypes'),
73 'type' => MENU_DEFAULT_LOCAL_TASK,
74 'weight' => -10,
75 );
76
77 $items[] = array( //add new types, edit names of existing types, delete types
78 'path' => 'admin/user/accounttypes/edit',
79 'title' => t('Edit'),
80 'callback' => 'drupal_get_form',
81 'callback arguments' => array('accounttypes_edit'),
82 'access' => user_access('administer accounttypes'),
83 'type' => MENU_CALLBACK,
84 );
85
86 $items[] = array( //set default account type
87 'path' => 'admin/user/accounttypes/default',
88 'title' => t('Set Default'),
89 'callback' => 'drupal_get_form',
90 'callback arguments' => array('accounttypes_default'),
91 'access' => user_access('administer accounttypes'),
92 'type' => MENU_CALLBACK,
93 );
94
95 $items[] = array( //assign roles to account types
96 'path' => 'admin/user/accounttypes/admin',
97 'title' => t('Assign Roles'),
98 'callback' => 'drupal_get_form',
99 'callback arguments' => array('accounttypes_admin'),
100 'access' => user_access('administer accounttypes'),
101 'type' => MENU_LOCAL_TASK,
102 );
103
104 $items[] = array( //assign existing users to the default role if they don't have a role
105 'path' => 'admin/user/accounttypes/assign_old_users',
106 'title' => t('Manage Old Users'),
107 'callback' => 'drupal_get_form',
108 'callback arguments' => array('accounttypes_assign_old'),
109 'access' => user_access('administer accounttypes'),
110 'type' => MENU_LOCAL_TASK,
111 'weight' => 10,
112 );
113 }
114
115 return $items;
116 } // function accounttypes_menu()
117
118 //-------------------------------setup the account type settings--------------------
119
120 /**
121 * Callback function: Set the default account type for new users.
122 *
123 * @return mixed
124 */
125 function accounttypes_default($id = NULL) {
126 if ($id == NULL) {
127 $id = 1;
128 }
129 $acctype = get_accounttypes($id);
130 $form['name'] = array(
131 '#type' => 'textfield',
132 '#title' => t('Account type name'),
133 '#default_value' => $acctype[$id],
134 '#disabled' => TRUE,
135 '#description' => t('Are you sure you want to set this as the default <em>account type</em>?'),
136 );
137 $form['atid'] = array(
138 '#type' => 'value',
139 '#value' => $id,
140 );
141 $form['submit'] = array(
142 '#type' => 'submit',
143 '#value' => t('Make default'),
144 );
145 return $form;
146 } //function accounttypes_default()
147
148 /**
149 * Validate the account type ID before saving as default
150 *
151 * @param string $form_id
152 * @param mixed $form_values
153 */
154 function accounttypes_default_validate($form_id, $form_values) {
155 if ($form_values['atid']) {
156 if ($form_values['op'] == t('Make default')) {
157 if (!db_result(db_query("SELECT * FROM {accounttypes} WHERE atid = %d", $form_values['atid']))) {
158 form_set_error('atid', t('The account type id %atid does not exist. Please choose another account type id.', array('%atid' => $form_values['atid'])));
159 }
160 }
161 }
162 else {
163 form_set_error('atid', t('Please choose a valid account type id.'));
164 }
165 } //function accounttypes_default_validate()
166
167 /**
168 * Submit the account type to be set as default.
169 *
170 * @param string $form_id
171 * @param mixed $form_values
172 * @return string
173 */
174 function accounttypes_default_submit($form_id, $form_values) {
175 if ($form_values['op'] == t('Make default')) {
176 variable_set('accounttypes_default', $form_values['atid']);
177 }
178 drupal_set_message(t('Default account type set.'));
179
180 return 'admin/user/accounttypes';
181 } //function accounttypes_default_submit()
182
183 /**
184 * Callback function: Assign existing users to the default account type if they don't have a account type.
185 *
186 * @return mixed
187 */
188 function accounttypes_assign_old() {
189 $form['submit'] = array(
190 '#type' => 'submit',
191 '#value' => t('Set users to default account type'),
192 '#description' => t('Are you sure you want to set all existing users without account types to the default account type?'),
193 );
194 return $form;
195 } //function accounttypes_assign_old()
196
197 /**
198 * Submit the account type to be set as default.
199 *
200 * @param string $form_id
201 * @param mixed $form_values
202 * @return string
203 */
204 function accounttypes_assign_old_submit($form_id, $form_values) {
205 $error = 0;
206 $results = db_query('SELECT uid FROM {users} ORDER BY uid');
207 while ($result = db_fetch_object($results)) {
208 $all_users[$result->uid] = $result->uid;
209 }
210 foreach ($all_users as $user => $uid) {
211 if (!_accounttypes_user_exists($uid)) {
212 $result1 = db_query("INSERT INTO {accounttypes_users} VALUES (%d, %d)", $uid, variable_get('accounttypes_default', STD_ACCOUNT_TYPE));
213 if (!$result1) {
214 $error = 1;
215 }
216 }
217 }
218 if ($error == 1) {
219 drupal_set_message(t('Error setting one or more users to the default account type.'), 'error');
220 }
221 else {
222 drupal_set_message(t('All existing users had their account type set to the current default.'));
223 }
224
225 return 'admin/user/accounttypes';
226 } //function accounttypes_assign_old_submit()
227
228 /**
229 * Callback function: Add, edit, or delete account types.
230 *
231 * <p>Here is where the admin interface is for creating new account types,editing their names, or deleting them.</p>
232 * @param integer $id
233 * The ID of the account type.
234 * @return mixed
235 */
236 function accounttypes_edit($id = NULL) {
237
238 if ($admin = user_access('administer accounttypes')) {
239 if ($id) {
240 // Display the edit account type form.
241 $result = db_query('SELECT * FROM {accounttypes} WHERE atid = %d', $id);
242 $acctype = db_fetch_object($result);
243 $form['name'] = array(
244 '#type' => 'textfield',
245 '#title' => t('Account type name'),
246 '#default_value' => $acctype->name,
247 '#size' => 20,
248 '#required' => TRUE,
249 '#maxlength' => 64,
250 '#description' => t('The name for this account type. Example: "basic", "premium", "dev group", "management".'),
251 );
252 $form['atid'] = array(
253 '#type' => 'value',
254 '#value' => $id,
255 );
256 $form['submit'] = array(
257 '#type' => 'submit',
258 '#value' => t('Save account type'),
259 );
260 $form['delete'] = array(
261 '#type' => 'submit',
262 '#value' => t('Delete account type'),
263 );
264 }
265 else {
266 $form['name'] = array(
267 '#type' => 'textfield',
268 '#size' => 20,
269 '#maxlength' => 64,
270 );
271 $form['submit'] = array(
272 '#type' => 'submit',
273 '#value' => t('Add account type'),
274 );
275 $form['#base'] = 'accounttypes_edit';
276 }
277 return $form;
278 }
279 } //function accounttype_admin()
280
281 /**
282 * Validate the account type name before adding or saving it
283 *
284 * @param string $form_id
285 * @param mixed $form_values
286 */
287 function accounttypes_edit_validate($form_id, $form_values) {
288 if ($form_values['name']) {
289 if ($form_values['op'] == t('Save account type')) {
290 if (db_result(db_query("SELECT COUNT(*) FROM {accounttypes} WHERE name = '%s' AND atid != %d", $form_values['name'], $form_values['atid']))) {
291 form_set_error('name', t('The account type name %name already exists. Please choose another account type name.', array('%name' => $form_values['name'])));
292 }
293 }
294 else if ($form_values['op'] == t('Add account type')) {
295 if (db_result(db_query("SELECT COUNT(*) FROM {accounttypes} WHERE name = '%s'", $form_values['name']))) {
296 form_set_error('name', t('The account type name %name already exists. Please choose another account type name.', array('%name' => $form_values['name'])));
297 }
298 }
299 }
300 else {
301 form_set_error('name', t('You must specify a valid account type name.'));
302 }
303 }//function accounttypes_edit_validate()
304
305 /**
306 * Submit the account type name to be saved, deleted, or added to the database.
307 *
308 * @param string $form_id
309 * @param mixed $form_values
310 * @return string
311 */
312 function accounttypes_edit_submit($form_id, $form_values) {
313 if ($form_values['op'] == t('Save account type')) {
314 if (db_query("UPDATE {accounttypes} SET name = '%s' WHERE atid = %d", $form_values['name'], $form_values['atid'])) {
315 drupal_set_message(t('The account type has been renamed.'));
316 }
317 else {
318 drupal_set_message(t('The account type has NOT been renamed.'), 'error');
319 }
320 }
321 else if ($form_values['op'] == t('Delete account type')) {
322 if ($form_values['atid'] != STD_ACCOUNT_TYPE) {
323 $default_acctype = variable_get('accounttypes_default', STD_ACCOUNT_TYPE);
324 if ($form_values['atid'] == $default_acctype) {
325 variable_set('accounttypes_default', STD_ACCOUNT_TYPE);
326 $default_acctype = STD_ACCOUNT_TYPE;
327 }
328 //grab the user ids that need to be changed and update them to the default account type (roles included)
329 $result = db_query("SELECT uid FROM {accounttypes_users} WHERE atid = %d", $form_values['atid']);
330 while ($uids = db_fetch_object($result)) {
331 $account = user_load(array('uid' => (int)$uids->uid));
332 if ($account !== FALSE) {
333 $account->selectAT = $default_acctype;
334 user_save($account, array('selectAT' => $default_acctype));
335 }
336 }
337 db_query("UPDATE {accounttypes_users} SET atid = %d WHERE atid = %d", $default_acctype, $form_values['atid']);
338 db_query("DELETE FROM {accounttypes} WHERE atid = %d", $form_values['atid']);
339 db_query("DELETE FROM {accounttypes_roles} WHERE atid = %d", $form_values['atid']);
340 drupal_set_message(t('The account type has been deleted.'));
341 }
342 else {
343 drupal_set_message(t('You cannot delete the account type with ID = 1. Change its name and role assignments instead.'), 'error');
344 }
345 }
346 else if ($form_values['op'] == t('Add account type')) {
347 db_query("INSERT INTO {accounttypes} (name) VALUES ('%s')", $form_values['name']);
348 drupal_set_message(t('The account type has been added.'));
349 }
350 return 'admin/user/accounttypes';
351 } //function accounttypes_edit_submit()
352
353 /**
354 * Theme for the add page of the edit function.
355 *
356 * <p>This lists all of the current account types with links to edit them or their assigned roles, followed with
357 * a field and button to add a new account type name to the list.</p>
358 * @param mixed $form
359 * @return mixed
360 */
361 function theme_accounttypes_new_edit($form) {
362 $default = variable_get('accounttypes_default', STD_ACCOUNT_TYPE);
363 $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => 3));
364 foreach (get_accounttypes() as $atid => $name) {
365 if ($atid == $default) {
366 $name .= ' <em>(default)</em>';
367 }
368 $edit_roles = l(t('edit roles'), 'admin/user/accounttypes/admin/' .$atid);
369 $edit_account_type = l(t('edit account type'), 'admin/user/accounttypes/edit/' .$atid);
370 $set_default = l(t('set as default'), 'admin/user/accounttypes/default/' .$atid);
371 $rows[] = array($name, $edit_account_type, $edit_roles, $set_default);
372 }
373 $rows[] = array(drupal_render($form['name']), array('data' => drupal_render($form['submit']), colspan => 3));
374
375 $output = drupal_render($form);
376 $output .= theme('table', $header, $rows);
377
378 return $output;
379 } //function theme_accounttypes_new_edit()
380
381 /**
382 * Register a callback for a certain flavor of the edit page.
383 *
384 * maybe there's a better way to do this?
385 * @return mixed
386 */
387 function accounttypes_forms() {
388 $forms['accounttypes_new_edit']['callback'] = 'accounttypes_edit';
389 return $forms;
390 } //function accounttypes_forms()
391
392 /**
393 * Retrieve an array of account types matching specified conditions.
394 *
395 * If no value is given the function, the entire list of account types will be returned, otherwise
396 * the account type matching the value will be returned.
397 * @param string $atid
398 * A string containing a accounttype ID. If set, only that account type is returned.
399 * @return
400 * An associative array with the account type id as the key and the account type name as value.
401 */
402 function get_accounttypes($atid = 0) {
403 $accounttypes = array();
404 if ($atid != 0) {
405 $result = db_query('SELECT * FROM {accounttypes} WHERE atid = %d ORDER BY name', $atid);
406 }
407 else {
408 $result = db_query('SELECT * FROM {accounttypes} ORDER BY name');
409 }
410
411 while ($acctype = db_fetch_object($result)) {
412 $accounttypes[$acctype->atid] = $acctype->name;
413 }
414 return $accounttypes;
415 } //function get_accounttypes()
416
417 /**
418 * Callback function: Assign roles to account types.
419 *
420 * @param int $atid
421 * @return mixed
422 */
423 function accounttypes_admin($atid = NULL) {
424 if (is_numeric($atid)) {
425 $result1 = db_query('SELECT ar.atid, ar.initial, r.name, r.rid FROM {accounttypes_roles} ar LEFT JOIN {role} r ON ar.rid = r.rid WHERE ar.atid = %d', $atid);
426 }
427 else {
428 $result1 = db_query('SELECT ar.atid, ar.initial, r.name, r.rid FROM {accounttypes_roles} ar LEFT JOIN {role} r ON ar.rid = r.rid ORDER BY name');
429 }
430
431 // Compile account type array:
432 while ($acctype = db_fetch_object($result1)) {
433 $acctype_roles[$acctype->atid][$acctype->name] = $acctype->rid;
434 $acctype_roles_initial[$acctype->atid][$acctype->name] = $acctype->initial;
435 }
436
437 if (is_numeric($atid)) {
438 $result2 = db_query('SELECT a.atid, a.name FROM {accounttypes} a WHERE a.atid = %d ORDER BY name', $atid);
439 }
440 else {
441 $result2 = db_query('SELECT a.atid, a.name FROM {accounttypes} a ORDER BY name');
442 }
443
444 $acctype_names = array();
445 while ($acctype2 = db_fetch_object($result2)) {
446 $acctype_names[$acctype2->atid] = $acctype2->name;
447 }
448
449 // Get roles:
450 $roles = db_query('SELECT r.name, r.rid FROM {role} r ORDER BY name');
451
452 // Render accounttype/role overview:
453 $options = array();
454 while ($role = db_fetch_object($roles)) {
455 if ($role->name == 'anonymous user') {
456 continue;
457 }
458 $options[$role->name] = '';
459 $form['roles'][$role->name] = array('#value' => t($role->name));//store a translated version of the role name
460 foreach ($acctype_names as $atid2 => $name) {
461 // Builds arrays for checked boxes for each account type
462 if (is_array($acctype_roles[$atid2]) && array_key_exists($role->name, $acctype_roles[$atid2])) {
463 $status[$atid2][] = $role->name;
464 }
465 if (is_array($acctype_roles_initial[$atid2]) && array_key_exists($role->name, $acctype_roles_initial[$atid2]) && $acctype_roles_initial[$atid2][$role->name]) {
466 $status_initial[$atid2][] = $role->name;
467 }
468 }
469 }
470 $form['checkboxes'] = array('#tree' => TRUE);
471 $form['checkboxes2'] = array('#tree' => TRUE);
472 // Have to build checkboxes here after checkbox arrays are built
473 foreach ($acctype_names as $atid3 => $name2) {
474 $form['checkboxes'][$atid3] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $status[$atid3]);
475 $form['checkboxes2'][$atid3] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => $status_initial[$atid3]);
476 $form['acctype_names'][$atid3] = array('#value' => $name2, '#tree' => TRUE);
477 }
478 $form['instructions'] = array(
479 '#type' => 'item',
480 '#value' => t('There are two columns for each Account Type. The first, labeled <em>Allow</em>, is used to assign the role to the Account Type.
481 The second, labeled <em>Init</em> designates that role as one that will automatically be assigned when the user first gets that Account Type.
482 Although these roles will initially be assigned to the user, they can be removed at any time just as those roles not initially given.'),
483 );
484 $form['submit'] = array('#type' => 'submit', '#value' => t('Save role associations'));
485
486 return $form;
487 } //function accounttypes_admin()
488
489 /**
490 * Submit the account type/role associations for storage
491 *
492 * @param string $form_id
493 * @param mixed $form_values
494 */
495 function accounttypes_admin_submit($form_id, $form_values) {
496 $allresults = db_query('SELECT * FROM {accounttypes}');
497 $allroles = db_query('SELECT * FROM {role}');
498 while ($role = db_fetch_object($allroles)) {
499 $allrole_ids[$role->name] = $role->rid;
500 }
501 while ($result = db_fetch_object($allresults)) {
502 if (isset($form_values['checkboxes'][$result->atid])) {
503 // Delete, so if we clear every checkbox we reset that role;
504 // otherwise permissions are active and denied everywhere.
505 db_query('DELETE FROM {accounttypes_roles} WHERE atid = %d', $result->atid);
506 $form_values['checkboxes'][$result->atid] = array_filter($form_values['checkboxes'][$result->atid]);
507 if (count($form_values['checkboxes'][$result->atid])) {
508 foreach ($form_values['checkboxes'][$result->atid] as $accid => $role_name) {
509 $role_id = $allrole_ids[$role_name];
510 if (!empty($form_values['checkboxes2'][$result->atid][$accid])) {
511 $initial = 1;
512 }
513 else {
514 $initial = 0;
515 }
516 db_query("INSERT INTO {accounttypes_roles} (atid, rid, initial) VALUES (%d, %d, %d)", $result->atid, $role_id, $initial);
517 }
518 }
519 }
520 }
521
522 drupal_set_message(t('The changes have been saved.'));
523
524 // Clear the cached pages and menus:
525 menu_rebuild();
526 } //function accounttypes_admin_submit()
527
528 /**
529 * Theme function to display the account type/role association grid
530 *
531 * @param $form The form for the table.
532 * @return string An HTML string representing the table.
533 */
534 function theme_accounttypes_admin($form) {
535 foreach (element_children($form['roles']) as $key) {
536 // Don't take form control structures
537 if (is_array($form['roles'][$key])) {
538 $row = array();
539 $row[] = array('data' => drupal_render($form['roles'][$key]), 'class' => 'role');
540 foreach (element_children($form['checkboxes']) as $atid) {
541 if (is_array($form['checkboxes'][$atid])) {
542 $row[] = array('data' => drupal_render($form['checkboxes'][$atid][$key]), 'align' => 'left', 'title' => t($key));
543 $row[] = array('data' => drupal_render($form['checkboxes2'][$atid][$key]), 'align' => 'left', 'title' => t($key));
544 }
545 }
546 $rows[] = $row;
547 }
548 }
549 $header[] = ('&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp\\'. t('Account Types'). '<br />' .t('Roles'). '&nbsp\\');
550 foreach (element_children($form['acctype_names']) as $atid) {
551 if (is_array($form['acctype_names'][$atid])) {
552 $name = drupal_render($form['acctype_names'][$atid]);
553 $header[] = array('data' => $name. '<br />Allow');
554 $header[] = array('data' => $name. '<br />Init');
555 }
556 }
557 $output = drupal_render($form['instructions']);
558 $output .= theme('table', $header, $rows, array('id' => 'roles'));
559 $output .= drupal_render($form);
560 return $output;
561 } //function theme_accounttypes_admin()
562
563 /**
564 * Alter user edit for account type stuff.
565 *
566 * <p>Alter the user edit form to show the account type radio selection before the roles.
567 * Also, restrict which roles are shown based on account type selected.</p>
568 *
569 * @param string $form_id the string identifying the form to be modified
570 * @param mixed &$form the form to modify
571 */
572 function accounttypes_form_alter($form_id, &$form) {
573
574 //common variable setup
575 $administer = user_access('administer accounttypes');
576 $assign = user_access('assign accounttypes');
577 $admin_user = user_access('administer access control');
578
579 $allacctypes = get_accounttypes();
580 $allroles = user_roles(1);
581 foreach ($allroles as $key => $value) {
582 $allroles[$key] = $key;
583 }
584 $na_accroles = array();
585 $accroles = array();
586 $accids = array();
587 //copy list to a temporary array to be manipulated for each account type(array2)
588 foreach ($allacctypes as $accid => $accname) {
589 $accids[$accid] = $accid;
590 $na_accroles[$accid] = $allroles;
591 $result = db_query('SELECT r.name, r.rid, ar.initial FROM {accounttypes_roles} ar LEFT JOIN {role} r ON ar.rid = r.rid WHERE ar.atid = %d', $accid);
592 while ($theentry = db_fetch_object($result)) {
593 $accroles[$accid][$theentry->rid] = $theentry->rid;//build the list of all roles assigned to this account type
594 $accinitial[$accid][$theentry->rid] = $theentry->initial;
595 unset($na_accroles[$accid][$theentry->rid]);//remove roles that are assigned to this account type, leaving those that are not
596 }
597 }
598
599 if (($uid = arg(1)) && is_numeric(arg(1))) {
600 if (!$defaultval = db_result(db_query('SELECT atid FROM {accounttypes_users} WHERE uid = %d', arg(1)))) {
601 $defaultval = variable_get('accounttypes_default', STD_ACCOUNT_TYPE);
602 }
603 }
604 else {
605 $defaultval = variable_get('accounttypes_default', STD_ACCOUNT_TYPE);
606 }
607
608 //make sure this only shows on one edit page
609 if (isset($form['_category'])) {
610 if ($form['_category']['#value'] == 'account') {
611 $one_page = 1;
612 }
613 else {
614 $one_page = 0;
615 }
616 }
617 else {
618 $one_page = 1;
619 }
620
621 //user edit and user add - admin perspective
622 if (($form_id == 'user_edit' || $form_id == 'user_register') && ($administer || $assign || $admin_user) && ($one_page == 1)) {
623
624 $formid = ($form_id == 'user_edit') ? 'user-edit' : 'user-register';
625 $form['account']['selectAT'] = array(
626 '#type' => 'radios',
627 '#title' => t('Account types'),
628 '#default_value' => $defaultval,
629 '#description' => t('Account types limit the roles that can be assigned to a user. Invalid roles will be unchecked upon changing this. Changes are not saved until you do so below.'),
630 '#weight' => 1,
631 );
632
633 foreach ($allacctypes as $accid => $accname) {
634 $form['account']['selectAT']['#options'][$accid] = $accname;
635 }
636
637 $form['account']['roles']['#weight'] = 2;
638 $form['account']['roles']['#description'] .= ' This list is restricted by the <em>Account Type</em> selected above.';
639 //TODO add list to end of checkbox description of acctypes that can activate it such as: babysitter(basic, music, turtle)
640
641 $output = '';
642 foreach ($accids as $atid) {//build the options for the javascript population of account type roles to be used as each is selected in turn
643 $temp_na_accroles = $na_accroles;
644 foreach ($accids as $b) {
645 if ($atid != $b) {
646 unset($temp_na_accroles[$b]);
647 }
648 }
649
650 $temp_accroles = $accroles;
651 foreach ($accids as $b) {
652 if ($atid != $b) {
653 unset($temp_accroles[$b]);
654 }
655 }
656
657 $temp_accinit = $accinitial;
658 foreach ($accids as $b) {
659 if ($atid != $b) {
660 unset($temp_accinit[$b]);
661 }
662 foreach ($temp_accinit as $id => $the_rest) {
663 foreach ($the_rest as $key => $value) {
664 if ($value == 1) {
665 $temp_accinit[$id][$key] = $key;
666 }
667 }
668 $temp_accinit[$id] = array_filter($temp_accinit[$id]);
669 }
670 }
671 $output .= '
672 function radioclick' .$atid. '() {
673 var nor = ' .drupal_to_js($temp_na_accroles). ';
674 var yesr = ' .drupal_to_js($temp_accroles). ';
675 var initr = ' .drupal_to_js($temp_accinit). ';
676 for (var y in nor[' .$atid. ']) {
677 $("#' .$formid. ' :checkbox[@id=edit-roles-"+ y +"]").removeAttr("checked");
678 $("#' .$formid. ' :checkbox[@id=edit-roles-"+ y +"]").attr("disabled", "disabled");
679 }
680 for (var b in yesr[' .$atid. ']) {
681 $("#' .$formid. ' :checkbox[@id=edit-roles-"+ b +"]").removeAttr("disabled");
682 }
683 for (var za in initr[' .$atid. ']) {
684 $("#' .$formid. ' :checkbox[@id=edit-roles-"+ za +"]").attr("checked", "checked");
685 }
686 }';
687 }
688
689 $output .= '
690 $(document).ready(function() {
691 radioclick' .$defaultval. '();';
692
693 foreach ($accids as $atid) {
694 $output .= '$("#' .$formid. ' :radio[@name=selectAT][@value=' .$atid. ']").click(function(){radioclick' .$atid. '();});';
695 }
696
697 $output .= '});';
698
699 drupal_add_js($output, 'inline');
700 }
701 elseif ($form_id == 'user_register') { //user registration form - user perspective
702 $form['account']['selectAT'] = array(
703 '#type' => 'hidden',
704 '#value' => $defaultval,
705 );
706 }
707 elseif ($form_id == 'user_edit') { //user edit form - user perspective
708 if (isset($form['_account']['selectAT'])) { //if they have an accounttype, use it (should be loaded from hook_user)
709 $current_accounttype = $form['_account']['selectAT'];
710 }
711 else { // otherwise, use the default
712 $current_accounttype = $defaultval;
713 }
714 $form['account']['selectAT'] = array(
715 '#type' => 'hidden',
716 '#value' => $current_accounttype,
717 );
718 }
719
720 //the admin user filter form - had to duplicate the code from user module to get this to work without changing core
721 if (($form_id == 'user_filter_form') && ($administer || $assign || $admin_user)) {
722 $session = &$_SESSION['user_overview_filter2'];
723 $session = is_array($session) ? $session : array();
724 $filters = user_filters();
725 $filters['acctype'] = array('title' => t('accnt type'),
726 'join' => "LEFT JOIN {accounttypes_users} au ON u.uid = au.uid",
727 'where' => "au.atid = %d",
728 'options' => get_accounttypes(),
729 );
730
731 $i = 0;
732 $form['filters'] = array('#type' => 'fieldset',
733 '#title' => t('Show only users where'),
734 '#theme' => 'user_filters',
735 );
736 foreach ($session as $filter) {
737 list($type, $value) = $filter;
738 $string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
739 // Merge an array of arrays into one if necessary.
740 $options = $type == 'permission' ? call_user_func_array('array_merge', $filters[$type]['options']) : $filters[$type]['options'];
741 //unset($form['filters']['current']);
742 $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $options[$value])));
743 }
744
745 foreach ($filters as $key => $filter) {
746 $names[$key] = $filter['title'];
747 $form['filters']['status'][$key] = array('#type' => 'select',
748 '#options' => $filter['options'],
749 );
750 }
751
752 $form['filters']['filter'] = array('#type' => 'radios',
753 '#options' => $names,
754 );
755 $form['filters']['buttons']['submit'] = array('#type' => 'submit',
756 '#value' => (count($session) ? t('Refine') : t('Filter'))
757 );
758 if (count($session)) {
759 $form['filters']['buttons']['undo'] = array('#type' => 'submit',
760 '#value' => t('Undo')
761 );
762 $form['filters']['buttons']['reset'] = array('#type' => 'submit',
763 '#value' => t('Reset')
764 );
765 }
766
767 unset($form['#submit']);
768 $form['#submit']['accounttypes_user_filter_form_submit'] = array($form);
769 }
770
771 // the display of the users
772 if (($form_id == 'user_admin_account') && ($administer || $assign || $admin_user)) {
773 $filter = accounttypes_user_build_filter_query();
774
775 //TODO make the account type column sortable
776 $header = array(
777 array(),
778 array('data' => t('Username'), 'field' => 'u.name'),
779 array('data' => t('Status'), 'field' => 'u.status'),
780 t('Account type'),
781 t('Roles'),
782 array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
783 array('data' => t('Last access'), 'field' => 'u.access'),
784 t('Operations')
785 );
786
787 $sql = 'SELECT DISTINCT u.uid, u.name, u.status, u.created, u.access FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid ' .$filter['join']. ' WHERE u.uid != 0 ' .$filter['where'];
788 $sql .= tablesort_sql($header);
789 $result = pager_query($sql, 50, 0, NULL, $filter['args']);
790
791 $form['options'] = array(
792 '#type' => 'fieldset',
793 '#title' => t('Update options'),
794 '#prefix' => '<div class="container-inline">',
795 '#suffix' => '</div>',
796 );
797 $options = array();
798 foreach (module_invoke_all('user_operations') as $operation => $array) {
799 $options[$operation] = $array['label'];
800 }
801 $form['options']['operation'] = array(
802 '#type' => 'select',
803 '#options' => $options,
804 '#default_value' => 'unblock',
805 );
806 $form['options']['submit'] = array(
807 '#type' => 'submit',
808 '#value' => t('Update'),
809 );
810 unset($form['#validate']);
811 unset($form['#submit']);
812 unset($form['#theme']);
813 $form['#validate']['accounttypes_user_admin_account_validate'] = array($form_id, $form_values, $form);
814 $form['#submit']['accounttypes_user_admin_account_submit'] = array($form_id, $form_values, $form);
815 $form['#theme'] = 'accounttypes_user_admin_account';
816
817 $destination = drupal_get_destination();
818
819 $status = array(t('blocked'), t('active'));
820 $roles = user_roles(1);
821
822 unset($form['name']);
823 unset($form['status']);
824 unset($form['theacctype']);
825 unset($form['roles']);
826 unset($form['member_for']);
827 unset($form['last_access']);
828 unset($form['operations']);
829
830 while ($account = db_fetch_object($result)) {
831 $accounts[$account->uid] = '';
832 $form['name'][$account->uid] = array('#value' => theme('username', $account));
833 $form['status'][$account->uid] = array('#value' => $status[$account->status]);
834
835 $user_acctype = db_fetch_object(db_query('SELECT atid FROM {accounttypes_users} WHERE uid = %d', $account->uid));
836 if (!$user_acctype) {
837 $form['theacctype'][$account->uid] = array('#value' => 'none');
838 }
839 else {
840 $acctype_result = db_fetch_object(db_query('SELECT name FROM {accounttypes} WHERE atid = %d', $user_acctype->atid));
841 $form['theacctype'][$account->uid] = array('#value' => $acctype_result->name);
842 }
843
844 $users_roles = array();
845 $roles_result = db_query('SELECT rid FROM {users_roles} WHERE uid = %d', $account->uid);
846 while ($user_role = db_fetch_object($roles_result)) {
847 $users_roles[] = $roles[$user_role->rid];
848 }
849 asort($users_roles);
850 $form['roles'][$account->uid][0] = array('#value' => theme('item_list', $users_roles));
851 $form['member_for'][$account->uid] = array('#value' => format_interval(time() - $account->created));
852 $form['last_access'][$account->uid] = array('#value' => $account->access ? t('@time ago', array('@time' => format_interval(time() - $account->access))) : t('never'));
853 $form['operations'][$account->uid] = array('#value' => l(t('edit'), "user/$account->uid/edit", array(), $destination));
854 }
855 $form['accounts'] = array(
856 '#type' => 'checkboxes',
857 '#options' => $accounts
858 );
859 $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
860 }
861 } //function accounttypes_form_alter()
862
863 //-------------------------------multiple user settings--------------------
864
865 /**
866 * Theme user administration overview.
867 *
868 * @param mixed $form
869 * @return string An HTML string representing the table.
870 */
871 function theme_accounttypes_user_admin_account($form) {
872 // Overview table:
873 $header = array(
874 theme('table_select_header_cell'),
875 array('data' => t('Username'), 'field' => 'u.name'),
876 array('data' => t('Status'), 'field' => 'u.status'),
877 t('Account type'),
878 t('Roles'),
879 array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
880 array('data' => t('Last access'), 'field' => 'u.access'),
881 t('Operations')
882 );
883
884 $output = drupal_render($form['options']);
885 if (isset($form['name']) && is_array($form['name'])) {
886 foreach (element_children($form['name']) as $key) {
887 $rows[] = array(
888 drupal_render($form['accounts'][$key]),
889 drupal_render($form['name'][$key]),
890 drupal_render($form['status'][$key]),
891 drupal_render($form['theacctype'][$key]),
892 drupal_render($form['roles'][$key]),
893 drupal_render($form['member_for'][$key]),
894 drupal_render($form['last_access'][$key]),
895 drupal_render($form['operations'][$key]),
896 );
897 }
898 }
899 else {
900 $rows[] = array(array('data' => t('No users available.'), 'colspan' => '7'));
901 }
902
903 $output .= theme('table', $header, $rows);
904 if ($form['pager']['#value']) {
905 $output .= drupal_render($form['pager']);
906 }
907
908 $output .= drupal_render($form);
909
910 return $output;
911 } //function theme_accounttypes_user_admin_account()
912
913 /**
914 * Submit the user administration update form.
915 *
916 * copied from user.module
917 * @param string $form_id
918 * @param mixed $form_values
919 * @param mixed $form
920 */
921 function accounttypes_user_admin_account_submit($form_id, $form_values, $form) {
922 $operations = module_invoke_all('user_operations');
923 $operation = $operations[$form_values['operation']];
924 // Filter out unchecked accounts.
925 $accounts = array_filter($form_values['accounts']);
926 if ($function = $operation['callback']) {
927 // Add in callback arguments if present.
928 if (isset($operation['callback arguments'])) {
929 $args = array_merge(array($accounts), $operation['callback arguments']);
930 }
931 else {
932 $args = array($accounts);
933 }
934 call_user_func_array($function, $args);
935
936 cache_clear_all('*', 'cache_menu', TRUE);
937 drupal_set_message(t('The update has been performed.'));
938 }
939 } //function accounttypes_user_admin_account_submit()
940
941 /**
942 * Validate the user administration update form.
943 *
944 * copied from user.module
945 * @param string $form_id
946 * @param mixed $form_values
947 * @param mixed $form
948 */
949 function accounttypes_user_admin_account_validate($form_id, $form_values, $form) {
950
951 $form_values['accounts'] = array_filter($form_values['accounts']);
952 if (count($form_values['accounts']) == 0) {
953 form_set_error('', t('No users selected.'));
954 return;
955 }
956
957 //Get the checked users, and the operation name.
958 $uids = array_filter($form_values['accounts']);
959 $operation_rid = explode('-', $form_values['operation']);
960 $operation = $operation_rid[0];
961 $oprid = $operation_rid[1];
962
963 //perform the check for each submitted user
964 foreach ($uids as $uid) {
965 $account = user_load(array('uid' => $uid));
966
967 switch ($operation) {
968 case 'add_role':
969 case 'remove_role':
970 case 'roleassign_add_role':
971 case 'roleassign_remove_role':
972 if (!accounttypes_check_role_restriction($account->selectAT, $oprid) || ($uid == 1)) {
973 form_set_value($form['accounts'][$uid], 0);
974 drupal_set_message(t('%user has an <em>account type</em> which is incompatible with the selected <em>role</em> and was not updated.', array('%user' => $account->name)), 'error');
975 unset($uids[$uid]);
976 if($account->selectAT == 0) {
977 drupal_set_message(t('%user has not been given a valid <em>account type</em>. Please edit their account to fix this issue.', array('%user' => $account->name)), 'error');
978 }
979 }
980 break;
981 }
982 }
983
984 if (!count($uids)) {
985 drupal_set_message('No valid users were selected for that change. Their <em>account type</em> prevents them from receiving that <em>role</em>. Please try again.', 'error');
986 drupal_goto('admin/user/user');
987 }
988 } //function accounttypes_user_admin_account_validate()
989
990 /**
991 * Check if the selected role is able to be applied to the selected user
992 *
993 * @param array $account The user's account information.
994 * @rid integer $rid A role ID.
995 * @return object $result A database object.
996 */
997 function accounttypes_check_role_restriction($account, $rid) {
998 return $result = (int)db_result(db_query('SELECT COUNT(*) FROM {accounttypes_roles} WHERE rid = %d AND atid = %d', $rid, $account));
999 } //function accounttypes_check_role_restriction()
1000
1001 /**
1002 * Implementation of hook_user_operations
1003 *
1004 * Change the account type of multiple users at once. Set callback for function that
1005 * will do the work.
1006 * @return ??? I don't remember.
1007 */
1008 function accounttypes_user_operations() {
1009 global $form_values;
1010
1011 if (user_access('administer accounttypes') || user_access('assign accounttypes')) {
1012 $allacctypes = get_accounttypes();
1013
1014 $change_acctypes = array();
1015 foreach ($allacctypes as $key => $value) {
1016 $change_acctypes['change_account_type-' .$key] = $value;
1017 }
1018
1019 if (count($allacctypes)) {
1020 $acctype_operations = array(
1021 t('Change the account type of the selected users') => array(
1022 'label' => $change_acctypes,
1023 ),
1024 );
1025
1026 $operations = $acctype_operations;
1027 }
1028 }
1029
1030 // If the form has been posted, we need to insert the proper data for role editing if necessary.
1031 if ($form_values) {
1032 $operation_atid = explode('-', $form_values['operation']);
1033 $operation = $operation_atid[0];
1034 $atid = $operation_atid[1];
1035 if ($operation == 'change_account_type') {
1036 if (user_access('administer accounttypes') || user_access('assign accounttypes')) {
1037 $operations[$form_values['operation']] = array(
1038 'callback' => 'accounttypes_multiple_accounttype_change',
1039 'callback arguments' => array($operation, $atid),
1040 );
1041 }
1042 else {
1043 watchdog('security', t('Detected malicious attempt to alter protected user fields.'), WATCHDOG_WARNING);
1044 return;
1045 }
1046 }
1047 }
1048
1049 return $operations;
1050 } //function accounttypes_user_operations()
1051
1052 /**
1053 * Deal with changing multiple users' account type.
1054 *
1055 * Check existing role assignments and remove those incompatible with the new account type
1056 * from the users_roles table. Alert the admin that some roles were changed.
1057 *
1058 * @param array $accounts The accounts to work on.
1059 * @param string $operation The operation to perform.
1060 * @param integer $atid The ID of the account type to use in the operation.
1061 */
1062 function accounttypes_multiple_accounttype_change($accounts, $operation, $atid) {
1063 foreach ($accounts as $uid) {
1064 $account = user_load(array('uid' => (int)$uid));
1065 // Skip changing the account type if they already have it.
1066 if ($account !== FALSE && ($account->selectAT != $atid) && ($account->uid != 1)) {
1067 user_save($account, array('selectAT' => $atid));
1068 }
1069 }
1070 } //function accounttypes_multiple_accounttype_change()
1071
1072 /**
1073 * Build query for user administration filters based on session.
1074 * copied from user.module and modified
1075 *
1076 * @return array A SQL query's WHERE and JOIN clauses and the args to go with them
1077 * in an associative array.
1078 */
1079 function accounttypes_user_build_filter_query() {
1080 $filters = user_filters();
1081 $filters['acctype'] = array('title' => t('accnt type'),
1082 'join' => 'LEFT JOIN {accounttypes_users} au ON u.uid = au.uid',
1083 'where' => 'au.atid = %d',
1084 'options' => get_accounttypes(),
1085 );
1086
1087 // Build query
1088 $where = $args = $join = array();
1089 foreach ($_SESSION['user_overview_filter2'] as $filter) {
1090 list($key, $value) = $filter;
1091 // This checks to see if this permission filter is an enabled permission for the authenticated role.
1092 // If so, then all users would be listed, and we can skip adding it to the filter query.
1093 if ($key == 'permission') {
1094 $account = new stdClass();
1095 $account->uid = 'user_filter';
1096 $account->roles = array(DRUPAL_AUTHENTICATED_RID => 1);
1097 if (user_access($value, $account)) {
1098 continue;
1099 }
1100 }
1101 $where[] = $filters[$key]['where'<