--- profile.module?rev=1.127 2006-02-07 16:33:41.000000000 +1100 +++ profile_5.module 2006-02-07 12:33:59.000000000 +1100 @@ -109,6 +109,22 @@ } /** + * Implementation of hook_perm(). + */ +function profile_perm() { + // Compile the permissions for each individual profile field. + $perms = array(); + $result = db_query('SELECT name FROM {profile_fields}'); + while ($record = db_fetch_object($result)) { + $perms[] = 'access ' .$record->name; + $perms[] = 'access own ' .$record->name; + $perms[] = 'edit own ' .$record->name; + } + + return $perms; +} + +/** * Implementation of hook_menu(). */ function profile_menu($may_cache) { @@ -153,12 +169,20 @@ return; } + // Do not allow browsing of fields by users who can't access the fields content + if (!_profile_perm_access_field($field)) { + drupal_access_denied(); + return; + } + // Compile a list of fields to show $fields = array(); $result = db_query('SELECT name, title, type, weight FROM {profile_fields} WHERE fid != %d AND visibility = %d ORDER BY weight', $field->fid, PROFILE_PUBLIC_LISTINGS); while ($record = db_fetch_object($result)) { + if (_profile_perm_access_field($record)) { $fields[] = $record; } + } // Determine what query to use: $arguments = array($field->fid); @@ -247,21 +271,23 @@ // We use LOWER('%s') instead of PHP's strtolower() to avoid UTF-8 conversion issues. } while ($field = db_fetch_object($result)) { + if (isset($edit[$field->name])) { if (_profile_field_serialize($field->type)) { $edit[$field->name] = serialize($edit[$field->name]); } db_query("DELETE FROM {profile_values} WHERE fid = %d AND uid = %d", $field->fid, $user->uid); db_query("INSERT INTO {profile_values} (fid, uid, value) VALUES (%d, %d, '%s')", $field->fid, $user->uid, $edit[$field->name]); // Mark field as handled (prevents saving to user->data). - $edit[$field->name] = NULL; + $edit[$field->name] = null; + } } } function profile_view_field($user, $field) { - // Only allow browsing of private fields for admins - $browse = user_access('administer users') || $field->visibility != PROFILE_PRIVATE; + // Only allow browsing of fields by users who can access the fields content for all users + $browse = _profile_perm_access_field($field); - if ($value = $user->{$field->name}) { + if (($value = $user->{$field->name}) && _profile_perm_access_field($field, $user)) { switch ($field->type) { case 'textfield': return check_plain($value); @@ -300,18 +326,11 @@ function profile_view_profile($user) { profile_load_profile($user); - - // Show private fields to administrators and people viewing their own account. - if (user_access('administer users') || $GLOBALS['user']->uid == $user->uid) { $result = db_query('SELECT * FROM {profile_fields} WHERE visibility != %d ORDER BY category, weight', PROFILE_HIDDEN); - } - else { - $result = db_query('SELECT * FROM {profile_fields} WHERE visibility != %d AND visibility != %d ORDER BY category, weight', PROFILE_PRIVATE, PROFILE_HIDDEN); - } while ($field = db_fetch_object($result)) { if ($value = profile_view_field($user, $field)) { - $description = ($field->visibility == PROFILE_PRIVATE) ? t('The content of this field is private and only visible to yourself.') : ''; + //$description = ($field->visibility == PROFILE_PRIVATE) ? t('The content of this field is private and only visible to yourself.') : ''; $title = ($field->type != 'checkbox') ? check_plain($field->title) : ''; $form = array('#title' => $title, '#value' => $value, '#description' => $description); $fields[$field->category][$field->name] = theme('item', $form); @@ -328,9 +347,10 @@ $output .= ' '. t('Put each item on a separate line or separate them by commas. No HTML allowed.'); } - if ($field->visibility == PROFILE_PRIVATE) { - $output .= ' '. t('The content of this field is kept private and will not be shown publicly.'); - } + // We could read the roles with permission to access this field and print them here. + //if ($field->visibility == PROFILE_PRIVATE) { + // $output .= ' '. t('The content of this field is kept private and will not be shown publicly.'); + //} return $output; } @@ -346,6 +366,7 @@ } while ($field = db_fetch_object($result)) { + if (_profile_perm_edit_field($field, $user)) { $category = $field->category; if (!isset($fields[$category])) { $fields[$category] = array('#type' => 'fieldset', '#title' => $category, '#weight' => $w++); @@ -379,6 +400,7 @@ break; } } + } return $fields; } @@ -394,7 +416,7 @@ return $fields; } -function profile_validate_profile($edit, $category) { +function profile_validate_profile($edit, $user, $category) { if ($_GET['q'] == 'user/register' || $_GET['q'] == 'admin/user/create') { $result = db_query('SELECT * FROM {profile_fields} WHERE register = 1 ORDER BY category, weight'); @@ -406,13 +428,17 @@ while ($field = db_fetch_object($result)) { if ($edit[$field->name]) { + if (!_profile_perm_edit_field($field, $user)) { + form_set_error($field->name, t('You do not have permission to edit %field.', array('%field' => theme('placeholder', $field->title)))); + } + if ($field->type == 'url') { if (!valid_url($edit[$field->name], true)) { form_set_error($field->name, t('The value provided for %field is not a valid URL.', array('%field' => theme('placeholder', $field->title)))); } } } - else if ($field->required && !user_access('administer users')) { + else if ($field->required && !user_access('administer users') && _profile_perm_edit_field($field, $user)) { form_set_error($field->name, t('The field %field is required.', array('%field' => theme('placeholder', $field->title)))); } } @@ -445,7 +471,7 @@ case 'form': return profile_form_profile($edit, $user, $category); case 'validate': - return profile_validate_profile($edit, $category); + return profile_validate_profile($edit, $user, $category); case 'categories': return profile_categories(); } @@ -660,4 +686,46 @@ return $type == 'date'; } +/* + * Returns true if the logged in user has permission to access/view the $field for $user. + */ +function _profile_perm_access_field($field, $user = NULL) { + return user_access('administer users') || user_access('access ' .$field->name) || (($user != NULL) && ($GLOBALS['user']->uid == $user->uid) && user_access('access own ' .$field->name)); +} + +/* + * Returns true if the logged in user has permission to edit the $field for $user. + */ +function _profile_perm_edit_field($field, $user) { + return user_access('administer users') || user_access('edit own ' .$field->name); +} + +function profile_search($op = 'search', $keys = null) { + switch ($op) { + case 'name': + if (user_access('access user profiles')) { + return t('profiles'); + } + case 'search': + if (user_access('access user profiles')) { + $find = array(); + // Replace wildcards with MySQL/PostgreSQL wildcards. + $keys = preg_replace('!\*+!', '%', $keys); + if (user_access('administer users')) { + // administrators don't have restrictions + $result = pager_query("SELECT u.* FROM {users} u INNER JOIN {profile_values} pv ON u.uid = pv.uid INNER JOIN {profile_fields} pf ON pv.fid = pf.fid WHERE LOWER(pv.value) LIKE LOWER('%%%s%%')", 15, 0, NULL, $keys); + } + else { + // non-administrators can only search public fields and active users + $result = pager_query("SELECT u.* FROM {users} u INNER JOIN {profile_values} pv ON u.uid = pv.uid INNER JOIN {profile_fields} pf ON pv.fid = pf.fid WHERE LOWER(pv.value) LIKE LOWER('%%%s%%') AND pf.visibility IN (%d, %d) AND u.status = 1", 15, 0, NULL, $keys, PROFILE_PUBLIC, PROFILE_PUBLIC_LISTINGS); + } + while ($account = db_fetch_object($result)) { + $user = user_load(array('uid'=>$account->uid)); + $view = implode(' | ', profile_view_profile($user)); + $find[] = array('title' => $account->name, 'link' => url("user/$account->uid/view"), 'snippet'=>search_excerpt($keys, $view)); + } + return $find; + } + } +}