- Patch #638070 by carlos8f, Gábor Hojtsy, ksenzee, pwolanin, chx, catch: router loaders causing a lot of database hits for access checks.
parent
fafabc7e2a
commit
a417a986ea
|
@ -2225,6 +2225,7 @@ function menu_reset_static_cache() {
|
|||
drupal_static_reset('menu_tree');
|
||||
drupal_static_reset('menu_tree_all_data');
|
||||
drupal_static_reset('menu_tree_page_data');
|
||||
drupal_static_reset('menu_load_all');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -213,9 +213,32 @@ function menu_overview_title($menu) {
|
|||
*
|
||||
* @param $menu_name
|
||||
* The unique name of a custom menu to load.
|
||||
* @return
|
||||
* Array defining the custom menu, or FALSE if the menu doesn't exist.
|
||||
*/
|
||||
function menu_load($menu_name) {
|
||||
return db_query("SELECT * FROM {menu_custom} WHERE menu_name = :menu", array(':menu' => $menu_name))->fetchAssoc();
|
||||
$all_menus = menu_load_all();
|
||||
return isset($all_menus[$menu_name]) ? $all_menus[$menu_name] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all custom menu data.
|
||||
*
|
||||
* @return
|
||||
* Array of custom menu data.
|
||||
*/
|
||||
function menu_load_all() {
|
||||
$custom_menus = &drupal_static(__FUNCTION__);
|
||||
if (!isset($custom_menus)) {
|
||||
if ($cached = cache_get('menu_custom', 'cache_menu')) {
|
||||
$custom_menus = $cached->data;
|
||||
}
|
||||
else {
|
||||
$custom_menus = db_query('SELECT * FROM {menu_custom}')->fetchAllAssoc('menu_name', PDO::FETCH_ASSOC);
|
||||
cache_set('menu_custom', $custom_menus, 'cache_menu');
|
||||
}
|
||||
}
|
||||
return $custom_menus;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,6 +265,7 @@ function menu_save($menu) {
|
|||
'description' => $menu['description'],
|
||||
))
|
||||
->execute();
|
||||
menu_cache_clear_all();
|
||||
|
||||
// Since custom menus are keyed by name and their machine-name cannot be
|
||||
// changed, there is no real differentiation between inserting and updating a
|
||||
|
@ -290,6 +314,7 @@ function menu_delete($menu) {
|
|||
->condition('menu_name', $menu['menu_name'])
|
||||
->execute();
|
||||
|
||||
menu_cache_clear_all();
|
||||
module_invoke_all('menu_delete', $menu);
|
||||
}
|
||||
|
||||
|
@ -710,16 +735,14 @@ function menu_form_node_type_form_alter(&$form, $form_state) {
|
|||
* titles as the values.
|
||||
*/
|
||||
function menu_get_menus($all = TRUE) {
|
||||
$system_menus = array_keys(menu_list_system_menus());
|
||||
$query = db_select('menu_custom');
|
||||
$query->addTag('translatable');
|
||||
$query->addField('menu_custom', 'menu_name', 'menu_name');
|
||||
$query->addField('menu_custom', 'title', 'title');
|
||||
if (!$all) {
|
||||
$query->condition('menu_name', $system_menus, 'NOT IN');
|
||||
if ($custom_menus = menu_load_all()) {
|
||||
if (!$all) {
|
||||
$custom_menus = array_diff_key($custom_menus, menu_list_system_menus());
|
||||
}
|
||||
foreach ($custom_menus as $menu_name => $menu) {
|
||||
$custom_menus[$menu_name] = t($menu['title']);
|
||||
}
|
||||
asort($custom_menus);
|
||||
}
|
||||
$query->orderBy('title');
|
||||
|
||||
return $query->execute()->fetchAllKeyed();
|
||||
return $custom_menus;
|
||||
}
|
||||
|
||||
|
|
|
@ -1347,16 +1347,32 @@ function user_register_access() {
|
|||
return user_is_anonymous() && variable_get('user_register', 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* User view access callback.
|
||||
*
|
||||
* @param $account
|
||||
* Can either be a full user object or a $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'))
|
||||
);
|
||||
|
||||
$uid = is_object($account) ? $account->uid : (int) $account;
|
||||
|
||||
// Never allow access to view the anonymous user account.
|
||||
if ($uid) {
|
||||
// Admins can view all, users can view own profiles at all times.
|
||||
if ($GLOBALS['user']->uid == $uid || user_access('administer users')) {
|
||||
return TRUE;
|
||||
}
|
||||
elseif (user_access('access user profiles')) {
|
||||
// At this point, load the complete account object.
|
||||
if (!is_object($account)) {
|
||||
$account = user_load($uid);
|
||||
}
|
||||
return (is_object($account) && $account->access && $account->status);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1520,17 +1536,18 @@ function user_menu() {
|
|||
'weight' => -8,
|
||||
);
|
||||
|
||||
$items['user/%user_uid_optional'] = array(
|
||||
// Use %user_uid_only_optional here to avoid loading the full user for
|
||||
// basic access checks.
|
||||
$items['user/%user_uid_only_optional'] = array(
|
||||
'title' => 'My account',
|
||||
'title callback' => 'user_page_title',
|
||||
'title arguments' => array(1),
|
||||
'page callback' => 'user_view',
|
||||
'page callback' => 'user_view_page',
|
||||
'page arguments' => array(1),
|
||||
'access callback' => 'user_view_access',
|
||||
'access arguments' => array(1),
|
||||
'weight' => -10,
|
||||
'menu_name' => 'user-menu',
|
||||
'file' => 'user.pages.inc',
|
||||
);
|
||||
|
||||
$items['user/%user/view'] = array(
|
||||
|
@ -1616,6 +1633,7 @@ function user_init() {
|
|||
* cannot be loaded.
|
||||
*
|
||||
* @see user_load()
|
||||
* @todo rethink the naming of this in Drupal 8.
|
||||
*/
|
||||
function user_uid_optional_load($uid = NULL) {
|
||||
if (!isset($uid)) {
|
||||
|
@ -1663,7 +1681,9 @@ function user_category_load($uid, &$map, $index) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the user id of the currently logged in user.
|
||||
* Returns $arg or the user ID of the current user if $arg is '%' or empty.
|
||||
*
|
||||
* @todo rethink the naming of this in Drupal 8.
|
||||
*/
|
||||
function user_uid_optional_to_arg($arg) {
|
||||
// Give back the current user uid when called from eg. tracker, aka.
|
||||
|
@ -1672,11 +1692,26 @@ function user_uid_optional_to_arg($arg) {
|
|||
return empty($arg) || $arg == '%' ? $GLOBALS['user']->uid : $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns $arg or the user ID of the current user if $arg is '%' or empty.
|
||||
*
|
||||
* @todo rethink the naming of this in Drupal 8.
|
||||
*/
|
||||
function user_uid_only_optional_to_arg($arg) {
|
||||
return user_uid_optional_to_arg($arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu item title callback - use the user name.
|
||||
*/
|
||||
function user_page_title($account) {
|
||||
return format_username($account);
|
||||
function user_page_title($uid) {
|
||||
if ($GLOBALS['user']->uid == $uid) {
|
||||
$account = $GLOBALS['user'];
|
||||
}
|
||||
else {
|
||||
$account = user_load($uid);
|
||||
}
|
||||
return is_object($account) ? format_username($account) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2107,6 +2142,16 @@ function _user_cancel($edit, $account, $method) {
|
|||
cache_clear_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Page callback wrapper for user_view().
|
||||
*/
|
||||
function user_view_page($uid) {
|
||||
// An administrator may try to view a non-existent account,
|
||||
// so we give them a 404 (versus a 403 for non-admins).
|
||||
$account = user_load($uid);
|
||||
return is_object($account) ? user_view($account) : MENU_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array for rendering the given user.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue