diff --git a/includes/common.inc b/includes/common.inc index 268e36b..8100950 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2494,12 +2494,21 @@ function drupal_deliver_html_page($page_callback_result) { if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) { // Standard 404 handler. - drupal_set_title(t('Page not found')); - $return = t('The requested page "@path" could not be found.', array('@path' => request_uri())); + $path = 'system/404'; + menu_set_active_item($path); + $return = menu_execute_active_handler($path, FALSE); } drupal_set_page_content($return); $page = element_info('page'); + // Use the path as key so that custom 404 don't get overriden by old + // cache. + $page['#cache'] = array( + 'keys' => explode('/', $path), + 'granularity' => DRUPAL_CACHE_PER_ROLE, + 'expire' => CACHE_TEMPORARY, + 'bin' => 'cache_page', + ); print drupal_render_page($page); break; @@ -2523,8 +2532,9 @@ function drupal_deliver_html_page($page_callback_result) { if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) { // Standard 403 handler. - drupal_set_title(t('Access denied')); - $return = t('You are not authorized to access this page.'); + $path = 'system/403'; + menu_set_active_item($path); + $return = menu_execute_active_handler($path, FALSE); } print drupal_render_page($return); diff --git a/modules/node/node.test b/modules/node/node.test index 5de6081..3acac22 100644 --- a/modules/node/node.test +++ b/modules/node/node.test @@ -1879,14 +1879,18 @@ class NodeBlockFunctionalTest extends DrupalWebTestCase { $this->assertTrue($bid, t('Custom block with visibility rule was created.')); // Verify visibility rules. + $this->drupalLogout(); + $this->drupalLogin($this->web_user); $this->drupalGet(''); - $this->assertNoText($custom_block['title'], t('Block was displayed on the front page.')); + $this->assertNoText($custom_block['title'], t('Block was not displayed on the front page.')); $this->drupalGet('node/add/article'); $this->assertText($custom_block['title'], t('Block was displayed on the node/add/article page.')); $this->drupalGet('node/' . $node1->nid); $this->assertText($custom_block['title'], t('Block was displayed on the node/N.')); // Delete the created custom block & verify that it's been deleted. + $this->drupalLogout(); + $this->drupalLogin($this->admin_user); $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/delete', array(), t('Delete')); $bid = db_query("SELECT 1 FROM {block_node_type} WHERE module = 'block' AND delta = :delta", array(':delta' => $bid))->fetchField(); $this->assertFalse($bid, t('Custom block was deleted.')); diff --git a/modules/simpletest/tests/menu.test b/modules/simpletest/tests/menu.test index 3c0952b..7c5bd4e 100644 --- a/modules/simpletest/tests/menu.test +++ b/modules/simpletest/tests/menu.test @@ -1374,11 +1374,10 @@ class MenuBreadcrumbTestCase extends DrupalWebTestCase { // Verify that we can access recent log entries, there is a corresponding // page title, and that the breadcrumb is empty (because the user is not // able to access "Administer", so the trail cannot recurse into it). - $trail = array(); + $trail = $home; $this->assertBreadcrumb('admin', $trail, t('Access denied')); $this->assertResponse(403); - $trail = $home; $this->assertBreadcrumb('admin/reports', $trail, t('Reports')); $this->assertNoResponse(403); diff --git a/modules/system/system.module b/modules/system/system.module index d7dc69c..2655612 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -510,6 +510,18 @@ function system_element_info() { * Implements hook_menu(). */ function system_menu() { + $items['system/403'] = array( + 'title' => 'Access denied', + 'page callback' => 'system_access_denied', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['system/404'] = array( + 'title' => 'Page not found', + 'page callback' => 'system_not_found', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); $items['system/files'] = array( 'title' => 'File download', 'page callback' => 'file_download', @@ -2136,6 +2148,26 @@ function system_admin_menu_block($item) { } /** + * Menu callback; returns a 403 error message. + * + * Page callback functions wanting to report an "access denied" message should + * not use this function. Instead see drupal_access_denied(). + */ +function system_access_denied() { + return array('#markup' => t('You are not authorized to access this page.')); +} + +/** + * Menu callback; returns a 404 error message. + * + * Page callback functions wanting to report a "not found" message should not + * use this function. Instead see drupal_not_found(). + */ +function system_not_found() { + return array('#markup' => t('The requested page could not be found.')); +} + +/** * Checks the existence of the directory specified in $form_element. * * This function is called from the system_settings form to check all core diff --git a/modules/system/system.test b/modules/system/system.test index 846653b..603b434 100644 --- a/modules/system/system.test +++ b/modules/system/system.test @@ -881,24 +881,26 @@ class AccessDeniedTestCase extends DrupalWebTestCase { $this->drupalGet('admin'); $this->assertText($node->title, t('Found the custom 403 page')); - // Logout and check that the user login block is shown on custom 403 pages. + // Logout and check that blocks and menu items are shown on custom 403 pages. $this->drupalLogout(); $this->drupalGet('admin'); $this->assertText($node->title, t('Found the custom 403 page')); $this->assertText(t('User login'), t('Blocks are shown on the custom 403 page')); + $this->assertText(t('Main menu'), t('Menu items are shown on the custom 403 page')); // Log back in and remove the custom 403 page. $this->drupalLogin($this->admin_user); $this->drupalPost('admin/config/system/site-information', array('site_403' => ''), t('Save configuration')); - // Logout and check that the user login block is shown on default 403 pages. + // Logout and check that blocks and menu items are shown on default 403 pages. $this->drupalLogout(); $this->drupalGet('admin'); $this->assertText(t('Access denied'), t('Found the default 403 page')); $this->assertResponse(403); $this->assertText(t('User login'), t('Blocks are shown on the default 403 page')); + $this->assertText(t('Main menu'), t('Menu items are shown on the default 403 page')); // Log back in, set the custom 403 page to /user and remove the block $this->drupalLogin($this->admin_user); @@ -944,20 +946,29 @@ class PageNotFoundTestCase extends DrupalWebTestCase { } function testPageNotFound() { + // Logout and check that blocks and menu items are shown on default 404 pages. + $this->drupalLogout(); $this->drupalGet($this->randomName(10)); $this->assertText(t('Page not found'), t('Found the default 404 page')); + $this->assertText(t('User login'), t('Blocks are shown on the default 404 page')); + $this->assertText(t('Main menu'), t('Menu items are shown on the default 404 page')); + // Log back in and add a custom 404 page. + $this->drupalLogin($this->admin_user); $edit = array( 'title' => $this->randomName(10), 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(100)))), ); $node = $this->drupalCreateNode($edit); - - // Use a custom 404 page. $this->drupalPost('admin/config/system/site-information', array('site_404' => 'node/' . $node->nid), t('Save configuration')); + // Logout and check that blocks and menu items are shown on custom 404 pages. + $this->drupalLogout(); + $this->drupalGet($this->randomName(10)); $this->assertText($node->title, t('Found the custom 404 page')); + $this->assertText(t('User login'), t('Blocks are shown on the custom 404 page')); + $this->assertText(t('Main menu'), t('Menu items are shown on the custom 404 page')); } }