public function ExceptionController::on404Html

Processes a NotFound exception into an HTTP 404 response.

Parameters

Symfony\Component\HttpKernel\Exception\FlattenException $exception: The flattened exception.

Sonfony\Component\HttpFoundation\Request $request: The request object that triggered this exception.

File

drupal/core/lib/Drupal/Core/ExceptionController.php, line 155
Definition of Drupal\Core\ExceptionController.

Class

ExceptionController
This controller handles HTTP errors generated by the routing system.

Namespace

Drupal\Core

Code

public function on404Html(FlattenException $exception, Request $request) {
  watchdog('page not found', check_plain($request->attributes
    ->get('system_path')), NULL, WATCHDOG_WARNING);

  // Check for and return a fast 404 page if configured.
  $exclude_paths = variable_get('404_fast_paths_exclude', FALSE);
  if ($exclude_paths && !preg_match($exclude_paths, $request
    ->getPathInfo())) {
    $fast_paths = variable_get('404_fast_paths', FALSE);
    if ($fast_paths && preg_match($fast_paths, $request
      ->getPathInfo())) {
      $fast_404_html = variable_get('404_fast_html', '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>');
      $fast_404_html = strtr($fast_404_html, array(
        '@path' => check_plain($request
          ->getUri()),
      ));
      return new Response($fast_404_html, 404);
    }
  }
  $system_path = $request->attributes
    ->get('system_path');

  // Keep old path for reference, and to allow forms to redirect to it.
  if (!isset($_GET['destination'])) {
    $_GET['destination'] = $system_path;
  }
  $path = $this->container
    ->get('path.alias_manager')
    ->getSystemPath(config('system.site')
    ->get('page.404'));
  if ($path && $path != $system_path) {

    // @todo Um, how do I specify an override URL again? Totally not clear. Do
    //   that and sub-call the kernel rather than using meah().
    // @todo The create() method expects a slash-prefixed path, but we store a
    //   normal system path in the site_404 variable.
    $subrequest = Request::create('/' . $path, 'get', array(), $request->cookies
      ->all(), array(), $request->server
      ->all());

    // The active trail is being statically cached from the parent request to
    // the subrequest, like any other static.  Unfortunately that means the
    // data in it is incorrect and does not get regenerated correctly for
    // the subrequest.  In this instance, that even causes a fatal error in
    // some circumstances because menu_get_active_trail() ends up having
    // a missing localized_options value.  To work around that, reset the
    // menu static variables and let them be regenerated as needed.
    // @todo It is likely that there are other such statics that need to be
    //   reset that are not triggering test failures right now.  If found,
    //   add them here.
    // @todo Refactor the breadcrumb system so that it does not rely on static
    //   variables in the first place, which will eliminate the need for this
    //   hack.
    drupal_static_reset('menu_set_active_trail');
    menu_reset_static_cache();
    $response = $this->container
      ->get('http_kernel')
      ->handle($subrequest, HttpKernel::SUB_REQUEST);
    $response
      ->setStatusCode(404, 'Not Found');
  }
  else {

    // @todo Replace this block with something cleaner.
    $return = t('The requested page "@path" could not be found.', array(
      '@path' => $request
        ->getPathInfo(),
    ));
    drupal_set_title(t('Page not found'));
    drupal_set_page_content($return);
    $page = element_info('page');
    $content = drupal_render_page($page);
    $response = new Response($content, 404);
  }
  return $response;
}