diff options
author | Dries Buytaert <dries@buytaert.net> | 2004-04-21 13:56:38 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2004-04-21 13:56:38 +0000 |
commit | 7231c88a326f92bdc2b1579ac6afb8f7f568170b (patch) | |
tree | b7586493410910be188d97440dbdf1d44b084b91 /includes | |
parent | 7976678719f6e04ecda315a6088ee0eb3cfb0318 (diff) | |
download | brdo-7231c88a326f92bdc2b1579ac6afb8f7f568170b.tar.gz brdo-7231c88a326f92bdc2b1579ac6afb8f7f568170b.tar.bz2 |
- Added support for 403 handling. Patch by JonBob. As a side benefit,
administrators will be able to define a custom 403 page, just as they
can define 404 pages now.
This needs to be documented in the "Changes since / migrating to ..."
pages.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/common.inc | 31 | ||||
-rw-r--r-- | includes/file.inc | 4 | ||||
-rw-r--r-- | includes/menu.inc | 61 |
3 files changed, 71 insertions, 25 deletions
diff --git a/includes/common.inc b/includes/common.inc index 4433791b8..7af2e13b0 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -80,7 +80,6 @@ function drupal_get_breadcrumb() { if (!isset($breadcrumb)) { $breadcrumb = menu_get_active_breadcrumb(); - array_pop($breadcrumb); } return $breadcrumb; @@ -253,24 +252,40 @@ function drupal_goto($url = NULL, $query = NULL, $fragment = NULL) { * Generates a 404 error if the request can not be handled. */ function drupal_not_found() { - header("HTTP/1.0 404 Not Found"); - watchdog("httpd", "404 error: '". check_query($_GET["q"]) ."' not found"); + header('HTTP/1.0 404 Not Found'); + watchdog('httpd', '404 error: "'. check_query($_GET['q']) .'" not found'); $path = drupal_get_normal_path(variable_get('site_404', '')); - + $status = MENU_FALLTHROUGH; if ($path) { menu_set_active_item($path); + $status = menu_execute_active_handler(); } - if ($path && menu_active_handler_exists()) { - menu_execute_active_handler(); - } - else { + if ($status != MENU_FOUND) { print theme('page', '', t('Page not found')); } } /** + * Generates a 403 error if the request is not allowed. + */ +function drupal_access_denied() { + header('HTTP/1.0 403 Forbidden'); + + $path = drupal_get_normal_path(variable_get('site_403', '')); + $status = MENU_FALLTHROUGH; + if ($path) { + menu_set_active_item($path); + $status = menu_execute_active_handler(); + } + + if ($status != MENU_FOUND) { + print theme('page', message_access(), t('Access denied')); + } +} + +/** * Flexible and powerful HTTP client implementation. Allows to GET, POST, PUT * or any other HTTP requests. Handles redirects. * diff --git a/includes/file.inc b/includes/file.inc index d3f6344a3..5c6994330 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -307,7 +307,7 @@ function file_transfer($source, $headers) { // Transfer file in 1024 byte chunks to save memory usage. $fd = fopen($source, 'rb'); while (!feof($fd)) { - print fgets($fd, 1024); + print fread($fd, 1024); } fclose($fd); exit(); @@ -323,7 +323,7 @@ function file_download() { foreach ($list as $module) { $headers = module_invoke($module, 'file_download', $file); if ($headers === -1) { - print theme('page', message_access()); + drupal_access_denied(); } elseif (is_array($headers)) { file_transfer($file, $headers); diff --git a/includes/menu.inc b/includes/menu.inc index 9a7c7234d..4ccd126cb 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -15,6 +15,10 @@ define('MENU_MODIFIED', 1); define('MENU_LOCKED', 2); define('MENU_CUSTOM', 3); +define('MENU_FALLTHROUGH', 0); +define('MENU_DENIED', 1); +define('MENU_FOUND', 2); + /** @} */ /** @@ -23,7 +27,10 @@ define('MENU_CUSTOM', 3); * @ingroup menu * @param $path Location then menu item refers to. * @param $title The title of the menu item to show in the rendered menu. - * @param $callback The function to call when this is the active menu item. + * @param $callback + * - string - The function to call when this is the active menu item. + * - MENU_FALLTHROUGH - Use the callback defined by the menu item's parent. + * - MENU_DENIED - Deny access to this menu item by this user. * @param $weight Heavier menu items sink down the menu. * @param $visibility * - MENU_SHOW - Show the menu item (default). @@ -31,11 +38,9 @@ define('MENU_CUSTOM', 3); * - MENU_HIDE_NOCHILD - Hide the menu item when it has no children. * @param $status * - MENU_NORMAL - The menu item can be moved (default). - * - MENU_MODIFIED - The administrator has moved or otherwise changed the menu item. * - MENU_LOCKED - The administrator may not modify the item. - * - MENU_CUSTOM - The menu item was created by the administrator. */ -function menu($path, $title, $callback = NULL, $weight = 0, $visibility = MENU_SHOW, $status = MENU_NORMAL) { +function menu($path, $title, $callback = MENU_FALLTHROUGH, $weight = 0, $visibility = MENU_SHOW, $status = MENU_NORMAL) { global $_menu; // add the menu to the flat list of menu items: @@ -90,7 +95,13 @@ function menu_get_trail($path) { $trail = array(); - $mid = menu_get_active_item(); + // Find the ID of the given path. + while ($path && !$menu['path index'][$path]) { + $path = substr($path, 0, strrpos($path, '/')); + } + $mid = $menu['path index'][$path]; + + // Follow the parents up the chain to get the trail. while ($mid && $menu['items'][$mid]) { array_unshift($trail, $mid); $mid = $menu['items'][$mid]['pid']; @@ -171,9 +182,13 @@ function menu_get_active_breadcrumb() { $links[] = l(t('Home'), ''); $trail = menu_get_trail($_GET['q']); + + // The last item in the trail is the page title; don't display it here. + array_pop($trail); + foreach ($trail as $mid) { - // Don't show menu items without valid link targets. - if ($menu['items'][$mid]['path'] != '') { + // Don't show hidden menu items or items without valid link targets. + if (isset($menu['visible'][$mid]) && $menu['items'][$mid]['path'] != '') { $links[] = _menu_render_item($mid); } } @@ -188,20 +203,26 @@ function menu_execute_active_handler() { $menu = menu_get_menu(); $path = $_GET['q']; - while ($path && (!$menu['path index'][$path] || !$menu['items'][$menu['path index'][$path]]['callback'])) { + while ($path && (!$menu['path index'][$path] || $menu['items'][$menu['path index'][$path]]['callback'] === MENU_FALLTHROUGH)) { $path = substr($path, 0, strrpos($path, '/')); } $mid = $menu['path index'][$path]; + if ($menu['items'][$mid]['callback'] === MENU_DENIED) { + return MENU_DENIED; + } - if ($menu['items'][$mid]['callback']) { + if (is_string($menu['items'][$mid]['callback'])) { $arg = substr($_GET['q'], strlen($menu['items'][$mid]['path']) + 1); if (isset($arg)) { - return call_user_func_array($menu['items'][$mid]['callback'], explode('/', $arg)); + call_user_func_array($menu['items'][$mid]['callback'], explode('/', $arg)); } else { - return call_user_func($menu['items'][$mid]['callback']); + call_user_func($menu['items'][$mid]['callback']); } + return MENU_FOUND; } + + return MENU_FALLTHROUGH; } /** @@ -211,11 +232,18 @@ function menu_active_handler_exists() { $menu = menu_get_menu(); $path = $_GET['q']; - while ($path && (!$menu['path index'][$path] || !$menu['items'][$menu['path index'][$path]]['callback'])) { + while ($path && (!$menu['path index'][$path] || $menu['items'][$menu['path index'][$path]]['callback'] === MENU_FALLTHROUGH)) { $path = substr($path, 0, strrpos($path, '/')); } $mid = $menu['path index'][$path]; + if ($menu['items'][$mid]['callback'] === MENU_FALLTHROUGH) { + return FALSE; + } + if ($menu['items'][$mid]['callback'] === MENU_DENIED) { + return FALSE; + } + return function_exists($menu['items'][$mid]['callback']); } @@ -298,7 +326,7 @@ function menu_build() { while ($item = db_fetch_object($result)) { // First, add any custom items added by the administrator. if ($item->status == MENU_CUSTOM) { - $_menu['items'][$item->mid] = array('pid' => $item->pid, 'path' => $item->path, 'title' => $item->title, 'callback' => NULL, 'weight' => $item->weight, 'visibility' => MENU_SHOW, 'status' => MENU_CUSTOM); + $_menu['items'][$item->mid] = array('pid' => $item->pid, 'path' => $item->path, 'title' => $item->title, 'callback' => MENU_FALLTHROUGH, 'weight' => $item->weight, 'visibility' => MENU_SHOW, 'status' => MENU_CUSTOM); $_menu['path index'][$item->path] = $item->mid; } // Don't display non-custom menu items if no module declared them. @@ -371,9 +399,12 @@ function menu_build_visible_tree($pid = 0) { $children = array_merge($children, menu_build_visible_tree($mid)); } } - if (($parent['visibility'] == MENU_SHOW) || - ($parent['visibility'] == MENU_HIDE_NOCHILD && count($children) > 1)) { + if ((($parent['visibility'] == MENU_SHOW) || + ($parent['visibility'] == MENU_HIDE_NOCHILD && count($children) > 1)) && $parent['callback'] !== MENU_DENIED) { $_menu['visible'][$pid] = array('title' => $parent['title'], 'path' => $parent['path'], 'children' => $children); + foreach ($children as $mid) { + $_menu['visible'][$mid]['pid'] = $pid; + } return array($pid); } else { |