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

Contents of /contributions/modules/role_weights/role_weights.module

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


Revision 1.28 - (show annotations) (download) (as text)
Tue Jul 7 15:10:06 2009 UTC (4 months, 2 weeks ago) by leafishpaul
Branch: MAIN
CVS Tags: HEAD
Changes since 1.27: +2 -2 lines
File MIME type: text/x-php
*** empty log message ***
1 <?php
2 // $Id: role_weights.module,v 1.27 2009/07/07 14:20:05 leafishpaul Exp $
3
4 /**
5 * @file
6 * Allows users to specify weights for user roles.
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function role_weights_help($path, $arg) {
13 switch ($path) {
14 case 'admin/help#role_weights':
15 $output = '<p>'. t('Role Weights is a small utility module to allow site admins to specify weights for user roles. Once installed, users with <em>administer users</em> permission can set weights for roles on the <a href="@roles">Roles configuration page</a>.', array('@roles' => url('admin/user/roles'))) .'</p>';
16 $output .= '<p>'. t('Admins can optionally enable sorting roles by weight on <a href="@roles">Roles</a> and <a href="@permissions">Permissions</a> by visiting the <a href="@roleweights">Role Weights configuration page</a>.', array('@roles' => url('admin/user/roles'), '@permissions' => url('admin/user/permissions'), '@roleweights' => url('admin/settings/role_weights'))) .'</p>';
17 $output .= '<p>'. t('For more information visit <a href="http://drupal.org/project/role_weights">Role Weights module page on drupal.org</a>.') .'</p>';
18 return $output;
19
20 case 'admin/settings/role_weights':
21 return t('<p>Configure how Role Weights affects the sorting of various core configuration pages. To set role weights, edit the relevant role on the <a href="@roles">Roles configuration page</a>.</p>', array('@roles' => url('admin/user/roles')));
22 }
23 }
24
25 /**
26 * Implementation of hook_menu().
27 */
28 function role_weights_menu() {
29 $items['admin/settings/role_weights'] = array(
30 'title' => 'Role Weights',
31 'description' => "Enable sorting roles by weight on the Roles and Permissions configuration pages.",
32 'page callback' => 'drupal_get_form',
33 'page arguments' => array('role_weights_settings_form'),
34 'access arguments' => array('administer users'),
35 'type' => MENU_NORMAL_ITEM,
36 );
37 return $items;
38 }
39
40 /**
41 * Implementation of hook_theme().
42 */
43 function role_weights_theme($existing, $type, $theme, $path) {
44 return array(
45 'role_weights_admin_new_role' => array(
46 'arguments' => array('form' => NULL),
47 ),
48 );
49 }
50
51 /**
52 * Form callback for the admin settings form.
53 */
54 function role_weights_settings_form() {
55 $form = array();
56
57 $form['role_weights_reorder_forms'] = array(
58 '#type' => 'checkbox',
59 '#title' => t('Enable sort by role weights'),
60 '#default_value' => variable_get('role_weights_reorder_forms', FALSE),
61 '#description' => t('Enable sorting roles by weight on the Roles (admin/user/roles) and Permissions (admin/user/permissions) pages. <em>Please note that this setting will override Drupal\'s default alphabetical sorting: if enabled and role weights are <strong>not</strong> set (or are equal), sorting will be less than satisfactory. There is an <a href="http://drupal.org/node/368088">issue open for this on drupal.org</a></em>'),
62 );
63
64 return system_settings_form($form);
65 }
66
67 /**
68 * Implementation of hook_form_alter().
69 *
70 * User.module's role handling is not fully Forms API
71 * compliant, in that it doesn't trigger drupal_submit_form,
72 * instead directly reading in the $_POST['edit']
73 * array. Here we 'fix' this problem by altering the
74 * submit behavior. This way, we can add to existing
75 * role forms, and also act on role deletion (deleting
76 * role_weights).
77 */
78 function role_weights_form_alter(&$form, &$form_state, $form_id) {
79
80 // Alter the 'user_admin_new_role' form to retheme.
81 if ($form_id == 'user_admin_new_role') {
82 $form['#theme'] = 'role_weights_admin_new_role';
83 }
84 elseif ($form_id == 'user_admin_role') {
85 $rid = arg(4);
86 _role_weights_shift_rid($rid, FALSE);
87
88 // Lock the anonymous and authenticated roles.
89 if (in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
90 switch ($rid) {
91 case DRUPAL_ANONYMOUS_RID:
92 $name = 'anonymous user';
93 break;
94 case DRUPAL_AUTHENTICATED_RID:
95 $name = 'authenticated user';
96 break;
97 }
98
99 $form['#prefix'] = t('<strong>@name</strong> (locked)', array('@name' => $name));
100
101 // Pass the name and rid as values, so that they will register properly on submit.
102 $form['name'] = array(
103 '#type' => 'value',
104 '#value' => $name,
105 );
106 $form['rid'] = array(
107 '#type' => 'value',
108 '#value' => $rid,
109 );
110 }
111
112 $weight = role_weights_get_weight($rid);
113 $form['weight'] = array(
114 '#type' => 'weight',
115 '#title' => t('Weight'),
116 '#description' => t('Set a lower number to have this role take precedence over other roles.'),
117 '#default_value' => $weight,
118 );
119 // By changing the values of the buttons, we force
120 // user_admin_role() to bypass its custom handling of
121 // form submission and instead use the regular Forms API
122 // method of building and submitting the form.
123 $form['submit']['#value'] = t('Save');
124 $form['delete']['#value'] = t('Delete');
125 // Reset weights so that the 'weight' field doesn't
126 // appear below the buttons.
127 $form['submit']['#weight'] = 9;
128 $form['delete']['#weight'] = 10;
129 $form['#submit'][] = 'role_weights_admin_role_submit';
130 }
131 elseif ($form_id == 'user_admin_perm' && variable_get('role_weights_reorder_forms', FALSE)) {
132 // For each role, fetch the weight, and add as a #weight on the row names and checkboxes
133 foreach ($form['checkboxes'] as $key => $value) {
134 if (is_numeric($key)) {
135 $weight = role_weights_get_weight($key);
136 $form['checkboxes'][$key]['#weight'] = $weight;
137 $form['role_names'][$key]['#weight'] = $weight;
138 }
139 }
140 // Resort according to the adjusted weights
141 uasort($form['checkboxes'], 'element_sort');
142 uasort($form['role_names'], 'element_sort');
143 }
144 }
145
146 /**
147 * Theme the 'user_admin_new_role' form.
148 *
149 * Based on theme_user_admin_new_role(), this version
150 * doesn't lock anonymous and authenticated user
151 * links, as we need to be able to navigate to them
152 * to provide weights. We will lock them in the role
153 * admin form instead.
154 *
155 */
156 function theme_role_weights_admin_new_role($form) {
157 $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => 2));
158
159 $user_roles = user_roles();
160 if (variable_get('role_weights_reorder_forms', FALSE)) {
161 uksort($user_roles, '_role_weights_rid_compare');
162 }
163
164 foreach ($user_roles as $rid => $name) {
165 $edit_permissions = l(t('edit permissions'), 'admin/user/permissions/'. $rid);
166
167 // Drupal core redirects if the rid is DRUPAL_ANONYMOUS_RID or DRUPAL_AUTHENTICATED_RID.
168 // We prevent this by shifting the rid.
169 _role_weights_shift_rid($rid);
170 $rows[] = array($name, l(t('edit role'), 'admin/user/roles/edit/'. $rid), $edit_permissions);
171 }
172 $rows[] = array(drupal_render($form['name']), array('data' => drupal_render($form['submit']), colspan => 2));
173
174 return drupal_render($form) . theme('table', $header, $rows);
175 }
176
177 /**
178 * Submission from role_weights_admin form.
179 */
180 function role_weights_admin_role_submit($form, &$form_state) {
181 $id = arg(4);
182 _role_weights_shift_rid($id, FALSE);
183
184 switch ($form_state['values']['op']) {
185 case t('Save'):
186 // Handle the role name update previously done in user_admin_role().
187 db_query("UPDATE {role} SET name = '%s' WHERE rid = %d", $form_state['values']['name'], $id);
188
189 // Now set weights.
190 _role_weights_set_weight($id, $form_state['values']['weight']);
191 drupal_set_message(t('The changes have been saved.'));
192 break;
193 case t('Delete'):
194 // Handle the role deletion previously done in user_admin_role().
195 db_query('DELETE FROM {role} WHERE rid = %d', $id);
196 db_query('DELETE FROM {permission} WHERE rid = %d', $id);
197
198 // Update the users who have this role set:
199 db_query('DELETE FROM {users_roles} WHERE rid = %d', $id);
200
201 // Now delete weight data.
202 db_query('DELETE FROM {role_weights} WHERE rid = %d', $id);
203
204 drupal_set_message(t('The role has been deleted.'));
205 break;
206 }
207
208 $form_state['redirect'] = 'admin/user/roles';
209 $form_state['rid'] = $id;
210 }
211
212 /**
213 * Returns a weight for a given role rid.
214 *
215 * @param $role_id
216 * A role rid
217 * @param $refresh
218 * If true, the static cache will be refreshed (used if you want to change
219 * the weight in the midst of a page load). This is done automatically by
220 * _role_weights_set_weight() - you should not need to do this.
221 * @return
222 * A corresponding weight for the role
223 */
224 function role_weights_get_weight($role_id = NULL, $refresh = FALSE) {
225 // Static cache the weights, to improve performance
226 static $weights;
227 if (!$weights || $refresh) {
228 $weights = _role_weights_get_weights();
229 }
230 return ($weights[$role_id] != NULL) ? $weights[$role_id] : 0;
231 }
232
233 /**
234 * Accepts a standard roles array from user object
235 * and returns the 'highest' based on the current weights
236 * settings.
237 *
238 * @TODO Perhaps deprecate this in favour of calling role_weights_get_weighted_max() with parameter.
239 * Included here so we don't break things in 5.x
240 * Leaving out a "role_weights_get_lowest" function
241 *
242 * @param $roles
243 * A role array containing a users roles - $rid -> $role_name
244 * @return
245 * A role id defining the users' single, 'highest' role
246 */
247 function role_weights_get_highest($roles) {
248 return role_weights_get_weighted_max($roles, 'lightest');
249 }
250
251 /**
252 * Accepts a standard roles array from user object
253 * and returns the 'lightest' or 'heaviest' based on
254 * the current weights settings.
255 *
256 * @param $roles
257 * A role array containing a users roles - $rid -> $role_name
258 * @param $weight_end
259 * Which weight to get - 'lightest' or 'heaviest'
260 * @return
261 * The lighest or heaviest role id from $roles
262 */
263 function role_weights_get_weighted_max($roles, $weight_end = 'lightest') {
264 $role_weights = _role_weights_get_weights();
265
266 if ($weight_end == 'lightest') {
267 asort($role_weights);
268 }
269 else {
270 arsort($role_weights);
271 }
272
273 // Run through $roles, returning FIRST role matched
274 foreach ($role_weights as $rid => $weight) {
275 if (array_key_exists($rid, $roles)) {
276 return $rid;
277 }
278 }
279 }
280
281 /**
282 * Sets role weight for a role based on form input.
283 */
284 function _role_weights_set_weight($rid, $weight) {
285 $exists = db_result(db_query('SELECT COUNT(*) FROM {role_weights} WHERE rid = %d', $rid));
286 if ($exists) {
287 db_query('UPDATE {role_weights} SET weight=%d WHERE rid=%d', $weight, $rid);
288 }
289 else {
290 db_query('INSERT INTO {role_weights} (rid, weight) VALUES (%d, %d)', $rid, $weight);
291 }
292 // Force role_weights_get_weight to refresh it's static cache
293 role_weights_get_weight(NULL, TRUE);
294 }
295
296 /**
297 * Returns current role weights
298 */
299 function _role_weights_get_weights() {
300 $weights = array();
301 $result = db_query('SELECT * FROM {role_weights}');
302 while ($row = db_fetch_object($result)) {
303 $weights[$row->rid] = $row->weight;
304 }
305 return $weights;
306 }
307
308 /**
309 * Helper function to shift role ids up or down.
310 */
311 function _role_weights_shift_rid(&$rid, $decrement = TRUE) {
312 if ($decrement === TRUE && in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
313 $rid = $rid - 2;
314 }
315 elseif ($decrement === FALSE && $rid < 1) {
316 $rid = $rid + 2;
317 }
318 }
319
320 /**
321 * compare function for sorting user_roles() by weight using uksort()
322 */
323 function _role_weights_rid_compare($r1, $r2) {
324 $r1_weight = role_weights_get_weight($r1);
325 $r2_weight = role_weights_get_weight($r2);
326
327 if ($r1_weight == $r2_weight) {
328 return 0;
329 }
330
331 return ($r1_weight < $r2_weight) ? -1 : 1;
332 }
333
334 /**
335 * Views 2 support
336 */
337 function role_weights_views_api() {
338 return array('api' => 2);
339 }
340
341 /**
342 * Token support
343 */
344 function role_weights_token_values($type, $object = NULL, $options = array()) {
345 if ($type == 'user') {
346 $user = $object;
347 $lightest_role = role_weights_get_weighted_max($user->roles, 'lightest');
348 $tokens['lightest-role'] = check_plain($user->roles[$lightest_role]);
349 $tokens['lightest-role-id'] = $lightest_role;
350
351 $heaviest_role = role_weights_get_weighted_max($user->roles, 'heaviest');
352 $tokens['heaviest-role'] = check_plain($user->roles[$heaviest_role]);
353 $tokens['heaviest-role-id'] = $heaviest_role;
354
355 return $tokens;
356 }
357 }
358
359 function role_weights_token_list($type = 'all') {
360 if ($type == 'user' || $type == 'all') {
361 $tokens['user']['lightest-role'] = t("The user's lightest role name");
362 $tokens['user']['lightest-role-id'] = t("The user's lightest role id");
363 $tokens['user']['heaviest-role'] = t("The user's heaviest role name");
364 $tokens['user']['heaviest-role-id'] = t("The user's heaviest role id");
365 return $tokens;
366 }
367 }

  ViewVC Help
Powered by ViewVC 1.1.2