diff --git a/src/CoreBundle/Controller/ExceptionController.php b/src/CoreBundle/Controller/ExceptionController.php index ffed9abf73a..d2e4ead0f0e 100644 --- a/src/CoreBundle/Controller/ExceptionController.php +++ b/src/CoreBundle/Controller/ExceptionController.php @@ -6,6 +6,7 @@ namespace Chamilo\CoreBundle\Controller; +use Chamilo\CoreBundle\Helpers\AccessUrlHelper; use Exception; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\ErrorHandler\Exception\FlattenException; @@ -13,6 +14,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class ExceptionController extends AbstractController { @@ -91,4 +93,33 @@ public function error(Request $request): Response 'exception' => $exception, ]); } + + #[Route(path: '/error/undefined-url', name: 'undefined_url_error')] + public function undefinedUrlError( + Request $request, + UrlGeneratorInterface $urlGenerator, + AccessUrlHelper $accessUrlHelper + ): Response { + $host = $request->getHost(); + + $accessUrl = $accessUrlHelper->getFirstAccessUrl(); + $themeHost = rtrim($accessUrl?->getUrl() ?? '', '/'); + $themeName = 'chamilo'; + + $cssUrl = $themeHost . $urlGenerator->generate('theme_asset', [ + 'name' => $themeName, + 'path' => 'colors.css', + ], UrlGeneratorInterface::ABSOLUTE_PATH); + + $logoUrl = $themeHost . $urlGenerator->generate('theme_asset', [ + 'name' => $themeName, + 'path' => 'images/header-logo.svg', + ], UrlGeneratorInterface::ABSOLUTE_PATH); + + return $this->render('@ChamiloCore/Exception/undefined_url.html.twig', [ + 'host' => $host, + 'cssUrl' => $cssUrl, + 'logoUrl' => $logoUrl, + ]); + } } diff --git a/src/CoreBundle/EventListener/AccessUrlValidationListener.php b/src/CoreBundle/EventListener/AccessUrlValidationListener.php new file mode 100644 index 00000000000..3689a6cde04 --- /dev/null +++ b/src/CoreBundle/EventListener/AccessUrlValidationListener.php @@ -0,0 +1,78 @@ +isMainRequest()) { + return; + } + + $request = $event->getRequest(); + $path = $request->getPathInfo(); + + // Prevent infinite redirection loop to the same error page + if (str_starts_with($path, '/error/undefined-url')) { + return; + } + + // Skip validation for static assets and special files + $excludedPrefixes = [ + '/build/', // Webpack build assets + '/theme/', // Legacy theme assets + '/favicon.ico', // Favicon + '/robots.txt', // Robots file + '/apple-touch-icon.png', // Mobile shortcut icon + ]; + + foreach ($excludedPrefixes as $prefix) { + if (str_starts_with($path, $prefix)) { + return; + } + } + + // Skip validation if multi-URL is not enabled + if (!$this->accessUrlHelper->isMultiple()) { + return; + } + + try { + // Try to get the current AccessUrl from the request + $accessUrl = $this->accessUrlHelper->getCurrent(); + + // If it's null, throw an exception to trigger redirection + if (null === $accessUrl) { + throw new \RuntimeException('AccessUrl not defined'); + } + } catch (\Throwable $e) { + // Log host and URI for debugging + $host = $request->getHost(); + $uri = $request->getUri(); + + // Redirect to custom error page + $url = $this->router->generate('undefined_url_error'); + $event->setResponse(new RedirectResponse($url)); + } + } +} diff --git a/src/CoreBundle/Helpers/AuthenticationConfigHelper.php b/src/CoreBundle/Helpers/AuthenticationConfigHelper.php index 5725945ec6f..c69b0795f2a 100644 --- a/src/CoreBundle/Helpers/AuthenticationConfigHelper.php +++ b/src/CoreBundle/Helpers/AuthenticationConfigHelper.php @@ -71,7 +71,7 @@ public function getAuthSources(?AccessUrl $url) ? $this->parameterBag->get('authentication') : []; - if (isset($authentication[$urlId->getId()])) { + if ($urlId && isset($authentication[$urlId->getId()])) { return $authentication[$urlId->getId()]; } diff --git a/src/CoreBundle/Helpers/SettingsManagerHelper.php b/src/CoreBundle/Helpers/SettingsManagerHelper.php index a5e29573194..e932dce9e71 100644 --- a/src/CoreBundle/Helpers/SettingsManagerHelper.php +++ b/src/CoreBundle/Helpers/SettingsManagerHelper.php @@ -31,7 +31,7 @@ public function getOverride(string $name, ?AccessUrl $accessUrl = null): mixed $accessUrl ??= $this->accessUrlHelper->getCurrent(); - if (isset($settingsOverrides[$accessUrl->getId()][$name])) { + if ($accessUrl && isset($settingsOverrides[$accessUrl->getId()][$name])) { return $settingsOverrides[$accessUrl->getId()][$name]; } diff --git a/src/CoreBundle/Helpers/ThemeHelper.php b/src/CoreBundle/Helpers/ThemeHelper.php index c38f61849da..ebc94193931 100644 --- a/src/CoreBundle/Helpers/ThemeHelper.php +++ b/src/CoreBundle/Helpers/ThemeHelper.php @@ -6,6 +6,7 @@ namespace Chamilo\CoreBundle\Helpers; +use Chamilo\CoreBundle\Entity\AccessUrl; use Chamilo\CoreBundle\Settings\SettingsManager; use Chamilo\CourseBundle\Settings\SettingsCourseManager; use League\Flysystem\FilesystemException; @@ -46,9 +47,12 @@ public function getVisualTheme(): string return $visualTheme; } + $visualTheme = null; $accessUrl = $this->accessUrlHelper->getCurrent(); - $visualTheme = $accessUrl->getActiveColorTheme()?->getColorTheme()->getSlug(); + if ($accessUrl instanceof AccessUrl) { + $visualTheme = $accessUrl->getActiveColorTheme()?->getColorTheme()->getSlug(); + } if ('true' == $this->settingsManager->getSetting('profile.user_selected_theme')) { $visualTheme = $this->userHelper->getCurrent()?->getTheme(); diff --git a/src/CoreBundle/Resources/config/services.yml b/src/CoreBundle/Resources/config/services.yml index 5ab88f49c86..73b153d7ea0 100644 --- a/src/CoreBundle/Resources/config/services.yml +++ b/src/CoreBundle/Resources/config/services.yml @@ -146,3 +146,10 @@ services: arguments: $registry: '@doctrine' $em: '@doctrine.orm.entity_manager' + + Chamilo\CoreBundle\EventListener\AccessUrlValidationListener: + arguments: + $accessUrlHelper: '@Chamilo\CoreBundle\Helpers\AccessUrlHelper' + $router: '@router' + tags: + - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 255 } diff --git a/src/CoreBundle/Resources/views/Exception/undefined_url.html.twig b/src/CoreBundle/Resources/views/Exception/undefined_url.html.twig new file mode 100644 index 00000000000..2e5454d4a0c --- /dev/null +++ b/src/CoreBundle/Resources/views/Exception/undefined_url.html.twig @@ -0,0 +1,42 @@ +{% extends '@ChamiloCore/Layout/layout_one_col.html.twig' %} + +{% block chamilo_head %} + {{ parent() }} + +{% endblock %} + +{% block content %} +
+ {{ 'Oops! URL not registered.'|trans }} +
+ ++ {{ 'The address "%host%" is not configured in this portal instance.'|trans({'%host%': host}) }} +
+ ++ {{ 'If the problem persists, please contact support.'|trans }} +
+ + + {{ 'Go to home page'|trans }} + +