Index: includes/menu.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/menu.inc,v retrieving revision 1.373 diff -u -p -r1.373 menu.inc --- includes/menu.inc 8 Jan 2010 07:30:34 -0000 1.373 +++ includes/menu.inc 9 Jan 2010 16:29:42 -0000 @@ -344,11 +344,22 @@ function menu_get_ancestors($parts) { * @return * The $data array unserialized and mapped. */ -function menu_unserialize($data, $map) { +function menu_unserialize($data, $map, &$item = NULL) { if ($data = unserialize($data)) { - foreach ($data as $k => $v) { + foreach ($data as $k => &$v) { + if (!is_numeric($k)) { + } if (is_int($v)) { - $data[$k] = isset($map[$v]) ? $map[$v] : ''; + if (!is_numeric($k)) { + // @todo - use a constant. + return $data; + } + if ($item && !empty($item['load_functions']) && empty($item['loaded']) && !_menu_load_objects($item, $map)) { + // An error occurred loading an object. + $item['access'] = FALSE; + return FALSE; + } + $v = isset($map[$v]) ? $map[$v] : ''; } } return $data; @@ -550,6 +561,7 @@ function _menu_load_objects(&$item, &$ma } } $item['load_functions'] = $load_functions; + $item['loaded'] = TRUE; } return TRUE; } @@ -573,15 +585,44 @@ function _menu_check_access(&$item, $map $item['access'] = (bool)$callback; } else { - $arguments = menu_unserialize($item['access_arguments'], $map); - // As call_user_func_array is quite slow and user_access is a very common - // callback, it is worth making a special case for it. - if ($callback == 'user_access') { - $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]); + $limit = 1; + // Functions can not contain : so this checks for serialized. + if (isset($callback[1]) && $callback[1] == ':') { + $callbacks = unserialize($callback); + if ($callbacks['#op'] == 'and') { + $limit = count($callbacks); + unset($callbacks['#op']); + } + else { + unset($callbacks['#op']); + } + $arguments = unserialize($item['access_arguments']); + } + else { + $callbacks = array($callback); + $arguments = array($item['access_arguments']); } - elseif (function_exists($callback)) { - $item['access'] = call_user_func_array($callback, $arguments); + $pass = 0; + foreach ($callbacks as $key => $callback) { + $current_arguments = menu_unserialize($arguments[$key], $map, $item); + if ($current_arguments === FALSE) { + // There was an error loading objects. + return; + } + // As call_user_func_array is quite slow and user_access is a very common + // callback, it is worth making a special case for it. + if ($callback == 'user_access') { + $access = (count($current_arguments) == 1) ? user_access($current_arguments[0]) : user_access($current_arguments[0], $current_arguments[1]); + } + elseif (function_exists($callback)) { + $access = call_user_func_array($callback, $current_arguments); + } + $pass += (bool)$access; + if ($pass == $limit) { + break; + } } + $item['access'] = $pass == $limit; } } @@ -793,11 +834,6 @@ function _menu_link_translate(&$item) { } // menu_tree_check_access() may set this ahead of time for links to nodes. if (!isset($item['access'])) { - if (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) { - // An error occurred loading an object. - $item['access'] = FALSE; - return FALSE; - } _menu_check_access($item, $map); } // For performance, don't localize a link the user can't access. @@ -3171,6 +3207,13 @@ function _menu_router_build($callbacks) if (is_bool($item['access callback'])) { $item['access callback'] = intval($item['access callback']); } + if (is_array($item['access callback'])) { + $item['access_callback']['#op'] = isset($item['access callback']['#op']) ? strtolower($item['access callback']['#op']) : 'and'; + $item['access callback'] = serialize($item['access callback']); + foreach ($item['access arguments'] as &$arguments) { + $arguments = serialize($arguments); + } + } $item += array( 'access arguments' => array(), Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1099 diff -u -p -r1.1099 user.module --- modules/user/user.module 7 Jan 2010 04:54:18 -0000 1.1099 +++ modules/user/user.module 9 Jan 2010 16:29:46 -0000 @@ -1337,16 +1337,14 @@ function user_register_access() { return user_is_anonymous() && variable_get('user_register', 1); } +function user_uid_is_current($uid) { + return ($GLOBALS['user']->uid == $uid); +} + function user_view_access($account) { return $account && $account->uid && - ( - // Always let users view their own profile. - ($GLOBALS['user']->uid == $account->uid) || - // Administrators can view all accounts. - user_access('administer users') || - // The user is not blocked and logged in at least once. - ($account->access && $account->status && user_access('access user profiles')) - ); + // The user is not blocked and logged in at least once. + ($account->access && $account->status && user_access('access user profiles')); } /** @@ -1515,8 +1513,17 @@ function user_menu() { 'title arguments' => array(1), 'page callback' => 'user_view', 'page arguments' => array(1), - 'access callback' => 'user_view_access', - 'access arguments' => array(1), + 'access callback' => array( + '#op' => 'or', + 'user_uid_is_current', + 'user_access', + 'user_view_access', + ), + 'access arguments' => array( + array('please menu system do not fire user_load so manu times' => 1), + array('administer users'), + array(1), + ), 'weight' => -10, 'menu_name' => 'user-menu', 'file' => 'user.pages.inc', @@ -1665,7 +1672,13 @@ function user_uid_optional_to_arg($arg) * Menu item title callback - use the user name. */ function user_page_title($account) { - return format_username($account); + if (is_numeric($account) && $GLOBALS['user']->uid == $account) { + $return = t('My account'); + } + else { + $return = format_username($account); + } + return $return; } /**