/**
  * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
  */
 public function onKernelException(GetResponseForExceptionEvent $event)
 {
     if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
         return;
     }
     $request = $event->getRequest();
     if ('' !== rtrim($request->getPathInfo(), '/')) {
         return;
     }
     $ex = $event->getException();
     if (!$ex instanceof NotFoundHttpException || !$ex->getPrevious() instanceof ResourceNotFoundException) {
         return;
     }
     $locale = $this->localeResolver->resolveLocale($request, $this->locales) ?: $this->defaultLocale;
     $request->setLocale($locale);
     $params = $request->query->all();
     unset($params['hl']);
     $event->setResponse(new RedirectResponse($request->getBaseUrl() . '/' . $locale . '/' . ($params ? '?' . http_build_query($params) : ''), 301));
 }
Ejemplo n.º 2
0
 private function matchI18n(array $params, $url)
 {
     if (false === $params) {
         return false;
     }
     if (isset($params['_locales'])) {
         if (false !== ($pos = strpos($params['_route'], I18nLoader::ROUTING_PREFIX))) {
             $params['_route'] = substr($params['_route'], $pos + strlen(I18nLoader::ROUTING_PREFIX));
         }
         if (!($currentLocale = $this->context->getParameter('_locale'))) {
             $currentLocale = $this->localeResolver->resolveLocale($this->container->get('request_stack')->getCurrentRequest(), $params['_locales']);
             // If the locale resolver was not able to determine a locale, then all efforts to
             // make an informed decision have failed. Just display something as a last resort.
             if (!$currentLocale) {
                 $currentLocale = reset($params['_locales']);
             }
         }
         if (!in_array($currentLocale, $params['_locales'], true)) {
             // We might want to allow the user to be redirected to the route for the given locale if
             //       it exists regardless of whether it would be on another domain, or the same domain.
             //       Below we assume that we do not want to redirect always.
             // if the available locales are on a different host, throw a ResourceNotFoundException
             if ($this->hostMap) {
                 // generate host maps
                 $hostMap = $this->hostMap;
                 $availableHosts = array_map(function ($locale) use($hostMap) {
                     return $hostMap[$locale];
                 }, $params['_locales']);
                 $differentHost = true;
                 foreach ($availableHosts as $host) {
                     if ($this->hostMap[$currentLocale] === $host) {
                         $differentHost = false;
                         break;
                     }
                 }
                 if ($differentHost) {
                     throw new ResourceNotFoundException(sprintf('The route "%s" is not available on the current host "%s", ' . 'but only on these hosts "%s".', $params['_route'], $this->hostMap[$currentLocale], implode(', ', $availableHosts)));
                 }
             }
             // no host map, or same host means that the given locale is not supported for this route
             throw new NotAcceptableLanguageException($currentLocale, $params['_locales']);
         }
         unset($params['_locales']);
         $params['_locale'] = $currentLocale;
     } else {
         if (isset($params['_locale']) && false !== ($pos = strpos($params['_route'], I18nLoader::ROUTING_PREFIX))) {
             $params['_route'] = substr($params['_route'], $pos + strlen(I18nLoader::ROUTING_PREFIX));
         }
     }
     // check if the matched route belongs to a different locale on another host
     if (isset($params['_locale']) && isset($this->hostMap[$params['_locale']]) && $this->context->getHost() !== ($host = $this->hostMap[$params['_locale']])) {
         if (!$this->redirectToHost) {
             throw new ResourceNotFoundException(sprintf('Resource corresponding to pattern "%s" not found for locale "%s".', $url, $this->getContext()->getParameter('_locale')));
         }
         return ['_controller' => 'JMS\\I18nRoutingBundle\\Controller\\RedirectController::redirectAction', 'path' => $url, 'host' => $host, 'permanent' => true, 'scheme' => $this->context->getScheme(), 'httpPort' => $this->context->getHttpPort(), 'httpsPort' => $this->context->getHttpsPort(), '_route' => $params['_route']];
     }
     // if we have no locale set on the route, we try to set one according to the localeResolver
     // if we don't do this all _internal routes will have the default locale on first request
     if (!isset($params['_locale']) && ($locale = $this->localeResolver->resolveLocale($this->container->get('request_stack')->getCurrentRequest(), $this->container->get('octava_mui.locale_manager')->getAllAliases()))) {
         $params['_locale'] = $locale;
     }
     return $params;
 }